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    menu_views.cpp
12  * \author  Daniel Steuernol steu@allacrost.org
13  * \author  Andy Gardner chopperdave@allacrost.org
14  * \brief   Source file for various menu views.
15  *****************************************************************************/
16 
17 #include <iostream>
18 #include <sstream>
19 
20 #include "audio.h"
21 #include "input.h"
22 #include "system.h"
23 
24 #include "menu.h"
25 
26 using namespace std;
27 using namespace hoa_menu::private_menu;
28 using namespace hoa_utils;
29 using namespace hoa_audio;
30 using namespace hoa_video;
31 using namespace hoa_gui;
32 using namespace hoa_global;
33 using namespace hoa_input;
34 using namespace hoa_system;
35 
36 namespace hoa_menu {
37 
38 namespace private_menu {
39 
40 
41 ////////////////////////////////////////////////////////////////////////////////
42 // CharacterWindow Class
43 ////////////////////////////////////////////////////////////////////////////////
44 
CharacterWindow()45 CharacterWindow::CharacterWindow() : _char_id(GLOBAL_CHARACTER_INVALID) {
46 }
47 
48 
49 
~CharacterWindow()50 CharacterWindow::~CharacterWindow() {
51 }
52 
53 
54 
SetCharacter(GlobalCharacter * character)55 void CharacterWindow::SetCharacter(GlobalCharacter *character) {
56 	_char_id = character->GetID();
57 
58 	_portrait.SetStatic(true);
59 	_portrait.Load("img/portraits/menu/" + character->GetFilename() + "_small.png", 100, 100);
60 } // void CharacterWindow::SetCharacter(GlobalCharacter *character)
61 
62 
63 
64 // Draw the window to the screen
Draw()65 void CharacterWindow::Draw() {
66 	// Call parent Draw method, if failed pass on fail result
67 	MenuWindow::Draw();
68 
69 	// check to see if this window is an actual character
70 	if (_char_id == hoa_global::GLOBAL_CHARACTER_INVALID)
71 		// no more to do here
72 		return;
73 
74 	VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_TOP, 0);
75 
76 	// Get the window metrics
77 	float x, y, w, h;
78 	GetPosition(x,y);
79 	GetDimensions(w,h);
80 	// Adjust the current position to make it look better
81 	y += 5;
82 
83 	GlobalCharacter *character = GlobalManager->GetCharacter(_char_id);
84 
85 	//Draw character portrait
86 	VideoManager->Move(x + 12, y + 8);
87 	_portrait.Draw();
88 
89 	// Write character name
90 	VideoManager->MoveRelative(150, -5);
91 	VideoManager->Text()->Draw(character->GetName(), TextStyle("title22"));
92 
93 	// Level
94 	VideoManager->MoveRelative(0,20);
95 	VideoManager->Text()->Draw(UTranslate("Lv: ") + MakeUnicodeString(NumberToString(character->GetExperienceLevel())), TextStyle("text20"));
96 
97 	// HP
98 	VideoManager->MoveRelative(0,20);
99 	VideoManager->Text()->Draw(UTranslate("HP: ") + MakeUnicodeString(NumberToString(character->GetHitPoints()) +
100 		" / " + NumberToString(character->GetMaxHitPoints())), TextStyle("text20"));
101 
102 	// SP
103 	VideoManager->MoveRelative(0,20);
104 	VideoManager->Text()->Draw(UTranslate("SP: ") + MakeUnicodeString(NumberToString(character->GetSkillPoints()) +
105 		" / " + NumberToString(character->GetMaxSkillPoints())), TextStyle("text20"));
106 
107 	// XP to level up
108 	VideoManager->MoveRelative(0, 20);
109 	VideoManager->Text()->Draw(UTranslate("XP to Next: ") +
110 		MakeUnicodeString(NumberToString(character->GetExperienceForNextLevel() - character->GetExperiencePoints())), TextStyle("text20"));
111 
112 	return;
113 }
114 
115 
116 ////////////////////////////////////////////////////////////////////////////////
117 // InventoryWindow Class
118 ////////////////////////////////////////////////////////////////////////////////
119 
120 
InventoryWindow()121 InventoryWindow::InventoryWindow() : _active_box(ITEM_ACTIVE_NONE) {
122 	_InitCategory();
123 	_InitInventoryItems();
124 	_InitCharSelect();
125 
126 	//Initializes the description textbox for the bottom window
127 	_description.SetOwner(this);
128 	_description.SetPosition(30.0f, 525.0f);
129 	_description.SetDimensions(800.0f, 80.0f);
130 	_description.SetDisplaySpeed(30);
131 	_description.SetTextStyle(TextStyle("text20"));
132 	_description.SetDisplayMode(VIDEO_TEXT_INSTANT);
133 	_description.SetTextAlignment(VIDEO_X_LEFT, VIDEO_Y_TOP);
134 
135 } // void InventoryWindow::InventoryWindow
136 
~InventoryWindow()137 InventoryWindow::~InventoryWindow()
138 {
139 }
140 
141 //Initializes the list of items
_InitInventoryItems()142 void InventoryWindow::_InitInventoryItems() {
143 	// Set up the inventory option box
144 	_inventory_items.SetPosition(500.0f, 170.0f);
145 	_inventory_items.SetDimensions(400.0f, 360.0f, 1, 255, 1, 6);
146 	_inventory_items.SetTextStyle(TextStyle("text20"));
147 	_inventory_items.SetCursorOffset(-52.0f, -20.0f);
148 	_inventory_items.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
149 	_inventory_items.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
150 	_inventory_items.Scissoring( true, false );
151 
152 	// Update the item text
153 	_UpdateItemText();
154 	if (_inventory_items.GetNumberOptions() > 0) {
155 		_inventory_items.SetSelection(0);
156 	}
157 	VideoManager->MoveRelative(-65, 20);
158 	// Initially hide the cursor
159 	_inventory_items.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
160 }
161 
162 //Initalizes character select
_InitCharSelect()163 void InventoryWindow::_InitCharSelect() {
164 	//character selection set up
165 	vector<ustring> options;
166 	uint32 size = GlobalManager->GetActiveParty()->GetPartySize();
167 
168 	_char_select.SetPosition(72.0f, 109.0f);
169 	_char_select.SetDimensions(360.0f, 432.0f, 1, 4, 1, 4);
170 	_char_select.SetCursorOffset(-50.0f, -6.0f);
171 	_char_select.SetTextStyle(TextStyle("text20"));
172 	_char_select.SetHorizontalWrapMode(VIDEO_WRAP_MODE_SHIFTED);
173 	_char_select.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
174 	_char_select.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
175 
176 	//Use a blank string so the cursor has somewhere to point
177 	//String is overdrawn by char portraits, so no matter
178 	for (uint32 i = 0; i < size; i++) {
179 		options.push_back(MakeUnicodeString(" "));
180 	}
181 
182 	_char_select.SetOptions(options);
183 	_char_select.SetSelection(0);
184 	_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
185 }
186 
187 //Initalizes the available item categories
_InitCategory()188 void InventoryWindow::_InitCategory() {
189 	_item_categories.SetPosition(458.0f, 120.0f);
190 	_item_categories.SetDimensions(448.0f, 30.0f, ITEM_CATEGORY_SIZE, 1, ITEM_CATEGORY_SIZE, 1);
191 	_item_categories.SetTextStyle(TextStyle("text20"));
192 
193 	_item_categories.SetCursorOffset(-52.0f, -20.0f);
194 	_item_categories.SetHorizontalWrapMode(VIDEO_WRAP_MODE_SHIFTED);
195 	_item_categories.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
196 	_item_categories.SetOptionAlignment(VIDEO_X_CENTER, VIDEO_Y_CENTER);
197 
198 	vector<ustring> options;
199 	options.push_back(UTranslate("All"));
200 	options.push_back(UTranslate("Itm"));
201 	options.push_back(UTranslate("Wpn"));
202 	options.push_back(UTranslate("Hlm"));
203 	options.push_back(UTranslate("Tor"));
204 	options.push_back(UTranslate("Arm"));
205 	options.push_back(UTranslate("Leg"));
206 	options.push_back(UTranslate("Key"));
207 
208 	_item_categories.SetOptions(options);
209 	_item_categories.SetSelection(ITEM_ALL);
210 	_item_categories.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
211 }
212 
213 // Activates/deactivates inventory window
Activate(bool new_status)214 void InventoryWindow::Activate(bool new_status) {
215 	// Set new status
216 	if (new_status) {
217 		_active_box = ITEM_ACTIVE_CATEGORY;
218 		// Update cursor state
219 		_item_categories.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
220 	}
221 	else {
222 		//FIX ME: Play N/A noise
223 		_active_box = ITEM_ACTIVE_NONE;
224 		_item_categories.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
225 		_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
226 	}
227 }
228 
229 // Updates the window
Update()230 void InventoryWindow::Update() {
231 
232 	//bool cancel = false;
233 	if ( GlobalManager->GetInventory()->size() == 0 )
234 	{
235 		// no more items in inventory, exit inventory window
236 		Activate(false);
237 		return;
238 	}
239 
240 	// Points to the active option box
241 	OptionBox *active_option = NULL;
242 
243 	_inventory_items.Update( SystemManager->GetUpdateTime() ); //For scrolling
244 
245 	switch (_active_box) {
246 		case ITEM_ACTIVE_CATEGORY:
247 			active_option = &_item_categories;
248 			break;
249 		case ITEM_ACTIVE_CHAR:
250 			active_option = &_char_select;
251 			break;
252 		case ITEM_ACTIVE_LIST:
253 			active_option = &_inventory_items;
254 			break;
255 	}
256 
257 	// Handle the appropriate input events
258 	if (InputManager->ConfirmPress())
259 	{
260 		active_option->InputConfirm();
261 	}
262 	else if (InputManager->CancelPress())
263 	{
264 		active_option->InputCancel();
265 	}
266 	else if (InputManager->LeftPress())
267 	{
268 		active_option->InputLeft();
269 	}
270 	else if (InputManager->RightPress())
271 	{
272 		active_option->InputRight();
273 	}
274 	else if (InputManager->UpPress())
275 	{
276 		active_option->InputUp();
277 	}
278 	else if (InputManager->DownPress())
279 	{
280 		active_option->InputDown();
281 	}
282 
283 	uint32 event = active_option->GetEvent();
284 	active_option->Update();
285 	// Handle confirm/cancel presses differently for each window
286 	switch (_active_box) {
287 		case ITEM_ACTIVE_NONE:
288 			break;
289 
290 		case ITEM_ACTIVE_CATEGORY:
291 		{
292 			// Activate the item list for this category
293 			if (event == VIDEO_OPTION_CONFIRM) {
294 				if (_inventory_items.GetNumberOptions() > 0) {
295 					_inventory_items.SetSelection(0);
296 					_item_categories.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
297 					_inventory_items.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
298 					_description.SetDisplayText(_item_objects[ 0 ]->GetDescription());
299 					_active_box = ITEM_ACTIVE_LIST;
300 					MenuMode::CurrentInstance()->_menu_sounds["confirm"].Play();
301 				} // if _inventory_items.GetNumberOptions() > 0
302 			} // if VIDEO_OPTION_CONFIRM
303 			// Deactivate inventory
304 			else if (event == VIDEO_OPTION_CANCEL) {
305 				MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
306 				_item_categories.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
307 				Activate(false);
308 			} // if VIDEO_OPTION_CANCEL
309 			break;
310 		} // case ITEM_ACTIVE_CATEGORY
311 
312 		case ITEM_ACTIVE_LIST:
313 		{
314 			// Activate the character select for application
315 			if (event == VIDEO_OPTION_CONFIRM) {
316 				_active_box = ITEM_ACTIVE_CHAR;
317 				_inventory_items.SetCursorState(VIDEO_CURSOR_STATE_BLINKING);
318 				_char_select.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
319 				MenuMode::CurrentInstance()->_menu_sounds["confirm"].Play();
320 			} // if VIDEO_OPTION_CONFIRM
321 			// Return to category selection
322 			else if (event == VIDEO_OPTION_CANCEL) {
323 				_active_box = ITEM_ACTIVE_CATEGORY;
324 				_inventory_items.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
325 				_item_categories.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
326 				MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
327 			} // else if VIDEO_OPTION_CANCEL
328 			else if ( event == VIDEO_OPTION_BOUNDS_UP || VIDEO_OPTION_BOUNDS_DOWN ) {
329 				_description.SetDisplayText(_item_objects[ _inventory_items.GetSelection() ]->GetDescription());
330 			} // else if VIDEO_OPTION_BOUNDS_UP
331 			break;
332 		} // case ITEM_ACTIVE_LIST
333 
334 		case ITEM_ACTIVE_CHAR:
335 		{
336 			// Use the item on the chosen character
337 			if (event == VIDEO_OPTION_CONFIRM) {
338 				GlobalObject* obj = _item_objects[ _inventory_items.GetSelection() ];
339 				if (obj->GetObjectType() == GLOBAL_OBJECT_ITEM) {
340 					GlobalItem *item = (GlobalItem*)GlobalManager->RetrieveFromInventory(obj->GetID());
341 					const ScriptObject* script_function = item->GetFieldUseFunction();
342 					if (script_function == NULL) {
343 						IF_PRINT_WARNING(MENU_DEBUG) << "item did not have a menu use function" << endl;
344 					}
345 					else {
346 						if (IsTargetParty(item->GetTargetType()) == true) {
347 							GlobalParty *ch_party = GlobalManager->GetActiveParty();
348 							ScriptCallFunction<void>(*script_function, ch_party);
349 							item->DecrementCount();
350 						} // if GLOBAL_TARGET_PARTY
351 						else { // Use on a single character only
352 							GlobalCharacter *ch = dynamic_cast<GlobalCharacter*>(GlobalManager->GetActiveParty()->GetActorAtIndex(_char_select.GetSelection()));
353 							ScriptCallFunction<void>(*script_function, ch);
354 							item->DecrementCount();
355 						}
356 					}
357 				} // if GLOBAL_OBJECT_ITEM
358 			} // if VIDEO_OPTION_CONFIRM
359 			// Return to item selection
360 			else if (event == VIDEO_OPTION_CANCEL) {
361 				_active_box = ITEM_ACTIVE_LIST;
362 				_inventory_items.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
363 				_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
364 				MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
365 			} // if VIDEO_OPTION_CANCEL
366 			break;
367 		} // case ITEM_ACTIVE_CHAR
368 	} // switch (_active_box)
369 
370 	// Update the item list
371 	_UpdateItemText();
372 } // void InventoryWindow::Update()
373 
374 // Updates the item list
_UpdateItemText()375 void InventoryWindow::_UpdateItemText() {
376 	_item_objects.clear();
377 	_inventory_items.ClearOptions();
378 
379 	switch (_item_categories.GetSelection()) {
380 		case ITEM_ALL:
381 		{
382 			std::map<uint32, GlobalObject*>* inv = GlobalManager->GetInventory();
383 			for (std::map<uint32, GlobalObject*>::iterator i = inv->begin(); i != inv->end(); i++) {
384 				_item_objects.push_back( i->second );
385 			}
386 		}
387 			break;
388 
389 		case ITEM_ITEM:
390 			_item_objects = _GetItemVector(GlobalManager->GetInventoryItems());
391 			break;
392 
393 		case ITEM_WEAPONS:
394 			_item_objects = _GetItemVector(GlobalManager->GetInventoryWeapons());
395 			break;
396 
397 		case ITEM_HEAD_ARMOR:
398 			_item_objects = _GetItemVector(GlobalManager->GetInventoryHeadArmor());
399 			break;
400 
401 		case ITEM_TORSO_ARMOR:
402 			_item_objects = _GetItemVector(GlobalManager->GetInventoryTorsoArmor());
403 			break;
404 
405 		case ITEM_ARM_ARMOR:
406 			_item_objects = _GetItemVector(GlobalManager->GetInventoryArmArmor());
407 			break;
408 
409 		case ITEM_LEG_ARMOR:
410 			_item_objects = _GetItemVector(GlobalManager->GetInventoryLegArmor());
411 			break;
412 
413 		case ITEM_KEY:
414 			_item_objects = _GetItemVector(GlobalManager->GetInventoryKeyItems());
415 			break;
416 	}
417 
418 	ustring text;
419 	std::vector<ustring> inv_names;
420 
421 	for (size_t ctr = 0; ctr < _item_objects.size(); ctr++) {
422 		text = MakeUnicodeString("<" + _item_objects[ctr]->GetIconImage().GetFilename() + "><32>     ") +
423 			_item_objects[ctr]->GetName() + MakeUnicodeString("<R><350>" + NumberToString(_item_objects[ctr]->GetCount()) + "   ");
424 		inv_names.push_back(text);
425 	}
426 
427 	_inventory_items.SetOptions(inv_names);
428 } // void InventoryWindow::UpdateItemText()
429 
430 
431 
Draw()432 void InventoryWindow::Draw() {
433 	MenuWindow::Draw();
434 
435 	// Update the item text in case the number of items changed.
436 	_UpdateItemText();
437 
438 	// Draw char select option box
439 	_char_select.Draw();
440 
441 	// Draw item categories option box
442 	_item_categories.Draw();
443 
444 	// Draw item list
445 	_inventory_items.Draw();
446 } // bool InventoryWindow::Draw()
447 
448 
449 ////////////////////////////////////////////////////////////////////////////////
450 // StatusWindow Class
451 ////////////////////////////////////////////////////////////////////////////////
452 
StatusWindow()453 StatusWindow::StatusWindow() :
454 	_char_select_active(false)
455 {
456 	// Get party size for iteration
457 	uint32 partysize = GlobalManager->GetActiveParty()->GetPartySize();
458 	StillImage portrait;
459 	GlobalCharacter* ch;
460 
461 	// Set up the full body portrait
462 	for (uint32 i = 0; i < partysize; i++) {
463 		ch = dynamic_cast<GlobalCharacter*>(GlobalManager->GetActiveParty()->GetActorAtIndex(i));
464 		portrait.SetStatic(true);
465 		portrait.Load("img/portraits/menu/" + ch->GetFilename() + "_large.png");
466 		_full_portraits.push_back(portrait);
467 	}
468 
469 	// Init char select option box
470 	_InitCharSelect();
471 } // StatusWindow::StatusWindow()
472 
473 
474 
~StatusWindow()475 StatusWindow::~StatusWindow() {
476 
477 }
478 
479 // Activate/deactivate window
Activate(bool new_value)480 void StatusWindow::Activate(bool new_value) {
481 	_char_select_active = new_value;
482 
483 	if (_char_select_active)
484 		_char_select.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
485 	else
486 		_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
487 }
488 
_InitCharSelect()489 void StatusWindow::_InitCharSelect() {
490 	//character selection set up
491 	vector<ustring> options;
492 	uint32 size = GlobalManager->GetActiveParty()->GetPartySize();
493 
494 	_char_select.SetPosition(72.0f, 109.0f);
495 	_char_select.SetDimensions(360.0f, 432.0f, 1, 4, 1, 4);
496 	_char_select.SetCursorOffset(-50.0f, -6.0f);
497 	_char_select.SetTextStyle(TextStyle("text20"));
498 	_char_select.SetHorizontalWrapMode(VIDEO_WRAP_MODE_SHIFTED);
499 	_char_select.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
500 	_char_select.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
501 
502 	// Use blank string so cursor can point somewhere
503 	for (uint32 i = 0; i < size; i++) {
504 		options.push_back(MakeUnicodeString(" "));
505 	}
506 
507 	_char_select.SetOptions(options);
508 	_char_select.SetSelection(0);
509 	_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
510 }
511 
512 // Updates the status window
Update()513 void StatusWindow::Update() {
514 	// check input values
515 	if (InputManager->UpPress())
516 	{
517 		_char_select.InputUp();
518 	}
519 	else if (InputManager->DownPress())
520 	{
521 		_char_select.InputDown();
522 	}
523 	else if (InputManager->CancelPress())
524 	{
525 		_char_select.InputCancel();
526 	}
527 
528 	if (_char_select.GetEvent() == VIDEO_OPTION_CANCEL) {
529 		Activate(false);
530 		MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
531 	}
532 	_char_select.Update();
533 } // void StatusWindow::Update()
534 
535 
536 // Draws the status window
Draw()537 void StatusWindow::Draw() {
538 	MenuWindow::Draw();
539 
540 	GlobalCharacter* ch =  dynamic_cast<GlobalCharacter*>(GlobalManager->GetActiveParty()->GetActorAtIndex(_char_select.GetSelection()));
541 
542 	// Set drawing system
543 	VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_TOP, VIDEO_BLEND, 0);
544 
545 	// window top corner is 432, 99
546 	VideoManager->Move(565, 130);
547 
548 	//Draw character name and level
549 	VideoManager->SetDrawFlags(VIDEO_X_CENTER, 0);
550 	VideoManager->Text()->Draw(ch->GetName());
551 
552 	VideoManager->MoveRelative(0, 25);
553 	VideoManager->Text()->Draw(UTranslate("Experience Level: ") + MakeUnicodeString(NumberToString(ch->GetExperienceLevel())));
554 
555 	VideoManager->SetDrawFlags(VIDEO_X_LEFT, 0);
556 
557 	//Draw all character stats
558 	VideoManager->MoveRelative(-55, 60);
559 	VideoManager->Text()->Draw(UTranslate("HP: ") + MakeUnicodeString(NumberToString(ch->GetHitPoints()) +
560 		" (" + NumberToString(ch->GetMaxHitPoints()) + ")"));
561 
562 	VideoManager->MoveRelative(0, 25);
563 	VideoManager->Text()->Draw(UTranslate("SP: ") + MakeUnicodeString(NumberToString(ch->GetSkillPoints()) +
564 		" (" + NumberToString(ch->GetMaxSkillPoints()) + ")"));
565 
566 	VideoManager->MoveRelative(0, 25);
567 	VideoManager->Text()->Draw(UTranslate("XP to Next: ") + MakeUnicodeString(NumberToString(ch->GetExperienceForNextLevel() - ch->GetExperiencePoints())));
568 
569 	VideoManager->MoveRelative(0, 25);
570 	VideoManager->Text()->Draw(UTranslate("Strength: ") + MakeUnicodeString(NumberToString(ch->GetStrength())));
571 
572 	VideoManager->MoveRelative(0, 25);
573 	VideoManager->Text()->Draw(UTranslate("Vigor: ") + MakeUnicodeString(NumberToString(ch->GetVigor())));
574 
575 	VideoManager->MoveRelative(0, 25);
576 	VideoManager->Text()->Draw(UTranslate("Fortitude: ") + MakeUnicodeString(NumberToString(ch->GetFortitude())));
577 
578 	VideoManager->MoveRelative(0, 25);
579 	VideoManager->Text()->Draw(UTranslate("Protection: ") + MakeUnicodeString(NumberToString(ch->GetProtection())));
580 
581 	VideoManager->MoveRelative(0, 25);
582 	VideoManager->Text()->Draw(UTranslate("Agility: ") + MakeUnicodeString(NumberToString(ch->GetAgility())));
583 
584 	VideoManager->MoveRelative(0, 25);
585 	VideoManager->Text()->Draw(UTranslate("Evade: ") + MakeUnicodeString(NumberToString(ch->GetEvade()) + "%"));
586 
587 	//Draw character full body portrait
588 	VideoManager->Move(855, 145);
589 	VideoManager->SetDrawFlags(VIDEO_X_RIGHT, VIDEO_Y_TOP, 0);
590 
591 	_full_portraits[_char_select.GetSelection()].Draw();
592 
593 	VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_TOP, 0);
594 
595 	_char_select.Draw();
596 } // void StatusWindow::Draw()
597 
598 ////////////////////////////////////////////////////////////////////////////////
599 // SkillsWindow Class
600 ////////////////////////////////////////////////////////////////////////////////
601 
SkillsWindow()602 SkillsWindow::SkillsWindow() :
603 	_active_box(SKILL_ACTIVE_NONE),
604 	_char_skillset(0)
605 {
606 	// Init option boxes
607 	_InitCharSelect();
608 	_InitSkillsList();
609 	_InitSkillsCategories();
610 
611 	_description.SetOwner(this);
612 	_description.SetPosition(30.0f, 525.0f);
613 	_description.SetDimensions(800.0f, 80.0f);
614 	_description.SetDisplaySpeed(30);
615 	_description.SetDisplayMode(VIDEO_TEXT_INSTANT);
616 	_description.SetTextAlignment(VIDEO_X_LEFT, VIDEO_Y_TOP);
617 	_description.SetTextStyle(TextStyle("text20"));
618 
619 } // SkillsWindow::SkillsWindow()
620 
621 
622 
Activate(bool new_status)623 void SkillsWindow::Activate(bool new_status) {
624 	// Activate window and first option box...or deactivate both
625 	if (new_status) {
626 		_char_select.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
627 		_active_box = SKILL_ACTIVE_CHAR;
628 	}
629 	else {
630 		_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
631 		_active_box = SKILL_ACTIVE_NONE;
632 	}
633 }
634 
635 
636 
_InitSkillsList()637 void SkillsWindow::_InitSkillsList() {
638 	// Set up the inventory option box
639 	_skills_list.SetPosition(500.0f, 170.0f);
640 	_skills_list.SetDimensions(180.0f, 360.0f, 1, 255, 1, 4);
641 	_skills_list.SetTextStyle(TextStyle("text20"));
642 	_skills_list.SetCursorOffset(-52.0f, -20.0f);
643 	_skills_list.SetHorizontalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
644 	_skills_list.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
645 	_skills_list.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
646 
647 	_UpdateSkillList();
648 	if (_skills_list.GetNumberOptions() > 0)
649 		_skills_list.SetSelection(0);
650 	_skills_list.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
651 
652 	// setup the cost option box
653 	_skill_cost_list.SetPosition(700.0f, 170.0f);
654 	_skill_cost_list.SetDimensions(180.0f, 360.0f, 1, 255, 1, 4);
655 	_skill_cost_list.SetTextStyle(TextStyle("text20"));
656 	_skill_cost_list.SetCursorOffset(-52.0f, -20.0f);
657 	_skill_cost_list.SetHorizontalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
658 	_skill_cost_list.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
659 	_skill_cost_list.SetOptionAlignment(VIDEO_X_RIGHT, VIDEO_Y_CENTER);
660 	_skill_cost_list.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
661 }
662 
663 
664 
_InitCharSelect()665 void SkillsWindow::_InitCharSelect() {
666 	//character selection set up
667 	vector<ustring> options;
668 	uint32 size = GlobalManager->GetActiveParty()->GetPartySize();
669 
670 	_char_select.SetPosition(72.0f, 109.0f);
671 	_char_select.SetDimensions(360.0f, 432.0f, 1, 4, 1, 4);
672 	_char_select.SetCursorOffset(-50.0f, -6.0f);
673 	_char_select.SetTextStyle(TextStyle("text20"));
674 	_char_select.SetHorizontalWrapMode(VIDEO_WRAP_MODE_SHIFTED);
675 	_char_select.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
676 	_char_select.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
677 
678 
679 	//Use blank strings....won't be seen anyway
680 	for (uint32 i = 0; i < size; i++) {
681 		options.push_back(MakeUnicodeString(" "));
682 	}
683 
684 	//Set options, selection and cursor state
685 	_char_select.SetOptions(options);
686 	_char_select.SetSelection(0);
687 	_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
688 }
689 
690 
691 
_InitSkillsCategories()692 void SkillsWindow::_InitSkillsCategories() {
693 	_skills_categories.SetPosition(458.0f, 120.0f);
694 	_skills_categories.SetDimensions(448.0f, 30.0f, SKILL_CATEGORY_SIZE, 1, SKILL_CATEGORY_SIZE, 1);
695 	_skills_categories.SetTextStyle(TextStyle("text20"));
696 	_skills_categories.SetCursorOffset(-52.0f, -20.0f);
697 	_skills_categories.SetHorizontalWrapMode(VIDEO_WRAP_MODE_SHIFTED);
698 	_skills_categories.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
699 	_skills_categories.SetOptionAlignment(VIDEO_X_CENTER, VIDEO_Y_CENTER);
700 
701 	// Create options
702 	vector<ustring> options;
703 	options.push_back(UTranslate("All"));
704 	options.push_back(UTranslate("Field"));
705 	options.push_back(UTranslate("Battle"));
706 
707 	// Set options and default selection
708 	_skills_categories.SetOptions(options);
709 	_skills_categories.SetSelection(SKILL_ALL);
710 	_skills_categories.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
711 } // void SkillsWindow::InitSkillsCategories()
712 
713 
714 
Update()715 void SkillsWindow::Update() {
716 	OptionBox *active_option = NULL;
717 
718 	//choose correct menu
719 	switch (_active_box) {
720 		case SKILL_ACTIVE_CATEGORY:
721 			active_option = &_skills_categories;
722 			break;
723 		case SKILL_ACTIVE_CHAR_APPLY:
724 		case SKILL_ACTIVE_CHAR:
725 			active_option = &_char_select;
726 			break;
727 		case SKILL_ACTIVE_LIST:
728 			active_option = &_skills_list;
729 			break;
730 	}
731 
732 	// Handle the appropriate input events
733 	if (InputManager->ConfirmPress())
734 	{
735 		active_option->InputConfirm();
736 	}
737 	else if (InputManager->CancelPress())
738 	{
739 		active_option->InputCancel();
740 	}
741 	else if (InputManager->LeftPress())
742 	{
743 		active_option->InputLeft();
744 	}
745 	else if (InputManager->RightPress())
746 	{
747 		active_option->InputRight();
748 	}
749 	else if (InputManager->UpPress())
750 	{
751 		active_option->InputUp();
752 	}
753 	else if (InputManager->DownPress())
754 	{
755 		active_option->InputDown();
756 	}
757 
758 	uint32 event = active_option->GetEvent();
759 	active_option->Update();
760 	switch (_active_box) {
761 		case SKILL_ACTIVE_CHAR_APPLY:
762 			// Handle skill application
763 			if (event == VIDEO_OPTION_CONFIRM)
764 			{
765 				GlobalSkill *skill = _GetCurrentSkill();
766 				GlobalCharacter* target = dynamic_cast<GlobalCharacter*>(GlobalManager->GetActiveParty()->GetActorAtIndex(_char_select.GetSelection()));
767 				GlobalCharacter* instigator = dynamic_cast<GlobalCharacter*>(GlobalManager->GetActiveParty()->GetActorAtIndex(_char_skillset));
768 
769 				const ScriptObject* script_function = skill->GetFieldExecuteFunction();
770 
771 				if (script_function == NULL) {
772 					IF_PRINT_WARNING(MENU_DEBUG) << "selected skill may not be executed in menus" << endl;
773 					break;
774 				}
775 				if (skill->GetSPRequired() > instigator->GetSkillPoints()) {
776 					IF_PRINT_WARNING(MENU_DEBUG) << "did not have enough skill points to execute skill " << endl;
777 					break;
778 				}
779 				ScriptCallFunction<void>(*script_function, target, instigator);
780 				instigator->SubtractSkillPoints(skill->GetSPRequired());
781 				MenuMode::CurrentInstance()->_menu_sounds["confirm"].Play();
782 			}
783 			else if (event == VIDEO_OPTION_CANCEL) {
784 				_active_box = SKILL_ACTIVE_LIST;
785 				_skills_list.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
786 				_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
787 				_char_select.SetSelection(_char_skillset);
788 				MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
789 			}
790 			break;
791 
792 		case SKILL_ACTIVE_CHAR:
793 			// Choose character for skillset
794 			if (event == VIDEO_OPTION_CONFIRM) {
795 				_active_box = SKILL_ACTIVE_CATEGORY;
796 				_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
797 				_skills_categories.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
798 				_char_skillset = _char_select.GetSelection();
799 				MenuMode::CurrentInstance()->_menu_sounds["confirm"].Play();
800 			}
801 			else if (event == VIDEO_OPTION_CANCEL) {
802 				Activate(false);
803 				_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
804 				MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
805 			}
806 			break;
807 
808 		case SKILL_ACTIVE_LIST:
809 			// Choose skill
810 			if (event == VIDEO_OPTION_CONFIRM) {
811 				GlobalSkill *skill = _GetCurrentSkill();
812 				if (skill->IsExecutableInField())
813 				{
814 					_active_box = SKILL_ACTIVE_CHAR_APPLY;
815 					_skills_list.SetCursorState(VIDEO_CURSOR_STATE_BLINKING);
816 					_char_select.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
817 					MenuMode::CurrentInstance()->_menu_sounds["confirm"].Play();
818 				}
819 				else
820 					MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
821 			}
822 			else if (event == VIDEO_OPTION_CANCEL) {
823 				_active_box = SKILL_ACTIVE_CATEGORY;
824 				MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
825 				_skills_list.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
826 				_skills_categories.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
827 			}
828 			break;
829 
830 		case SKILL_ACTIVE_CATEGORY:
831 			// Choose skill type
832 			if (event == VIDEO_OPTION_CONFIRM) {
833 				_skills_list.SetSelection(0);
834 				if (_skills_list.GetNumberOptions() > 0) {
835 					_active_box = SKILL_ACTIVE_LIST;
836 					_skills_categories.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
837 					_skills_list.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
838 					MenuMode::CurrentInstance()->_menu_sounds["confirm"].Play();
839 				}
840 				else {
841 					MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
842 				}
843 			}
844 			else if (event == VIDEO_OPTION_CANCEL) {
845 				_active_box = SKILL_ACTIVE_CHAR;
846 				MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
847 				_skills_categories.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
848 				_char_select.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
849 				_char_select.SetSelection(_char_skillset);
850 			}
851 			break;
852 	}
853 
854 	if (_active_box != SKILL_ACTIVE_CHAR_APPLY)
855 		_UpdateSkillList();
856 
857 	if (_skills_list.GetNumberOptions() > 0 && _skills_list.GetSelection() >= 0 && static_cast<int32>(_skills_list.GetNumberOptions()) > _skills_list.GetSelection())
858 	{
859 		GlobalSkill *skill = _GetCurrentSkill();
860 		string desc = MakeStandardString(skill->GetName()) + "\n\n" + MakeStandardString(skill->GetDescription());
861 		_description.SetDisplayText(MakeUnicodeString(desc));
862 	}
863 
864 } // void SkillsWindow::Update()
865 
_GetCurrentSkill()866 GlobalSkill *SkillsWindow::_GetCurrentSkill()
867 {
868 	GlobalCharacter* ch = dynamic_cast<GlobalCharacter*>(GlobalManager->GetActiveParty()->GetActorAtIndex(_char_skillset));
869 
870 	vector<GlobalSkill *> *menu_skills = new vector<GlobalSkill *>();
871 	vector<GlobalSkill *> *battle_skills = new vector<GlobalSkill *>();
872 	vector<GlobalSkill *> *all_skills = new vector<GlobalSkill *>();
873 
874 	_BuildMenuBattleSkillLists(ch->GetAttackSkills(), menu_skills, battle_skills, all_skills);
875 	_BuildMenuBattleSkillLists(ch->GetDefenseSkills(), menu_skills, battle_skills, all_skills);
876 	_BuildMenuBattleSkillLists(ch->GetSupportSkills(), menu_skills, battle_skills, all_skills);
877 
878 	GlobalSkill *skill;
879 	switch (_skills_categories.GetSelection())
880 	{
881 	case SKILL_ALL:
882 		skill = all_skills->at(_skills_list.GetSelection());
883 		break;
884 	case SKILL_BATTLE:
885 		skill = battle_skills->at(_skills_list.GetSelection());
886 		break;
887 	case SKILL_FIELD:
888 		skill = menu_skills->at(_skills_list.GetSelection());
889 		break;
890 	default:
891 		skill = NULL;
892 		cerr << "MENU ERROR: Invalid skill type in SkillsWindow::_GetCurrentSkill()" << endl;
893 		break;
894 	}
895 
896 	return skill;
897 }
898 
899 
_UpdateSkillList()900 void SkillsWindow::_UpdateSkillList() {
901 	GlobalCharacter* ch = dynamic_cast<GlobalCharacter*>(GlobalManager->GetActiveParty()->GetActorAtIndex(_char_select.GetSelection()));
902 	assert(ch);
903 	vector<ustring> options;
904 	vector<ustring> cost_options;
905 
906 	vector<GlobalSkill *> *menu_skills = new vector<GlobalSkill *>();
907 	vector<GlobalSkill *> *battle_skills = new vector<GlobalSkill *>();
908 	vector<GlobalSkill *> *all_skills = new vector<GlobalSkill *>();
909 
910 	_BuildMenuBattleSkillLists(ch->GetAttackSkills(), menu_skills, battle_skills, all_skills);
911 	_BuildMenuBattleSkillLists(ch->GetDefenseSkills(), menu_skills, battle_skills, all_skills);
912 	_BuildMenuBattleSkillLists(ch->GetSupportSkills(), menu_skills, battle_skills, all_skills);
913 
914 	vector<GlobalSkill *>::iterator i;
915 
916 	switch (_skills_categories.GetSelection()) {
917 		case SKILL_ALL:
918 // 			_skills_list.SetSize(1, all_skills->size());
919 // 			_skill_cost_list.SetSize(1, all_skills->size());
920 
921 			for (i = all_skills->begin(); i != all_skills->end(); ++i)
922 			{
923 				options.push_back((*i)->GetName());
924 				string cost = NumberToString((*i)->GetSPRequired()) + " SP";
925 				cost_options.push_back(MakeUnicodeString(cost));
926 			}
927 			break;
928 		case SKILL_BATTLE:
929 // 			_skills_list.SetSize(1,battle_skills->size());
930 // 			_skill_cost_list.SetSize(1, battle_skills->size());
931 
932 			for (i = battle_skills->begin(); i != battle_skills->end(); ++i)
933 			{
934 				options.push_back((*i)->GetName());
935 				string cost = NumberToString((*i)->GetSPRequired()) + " SP";
936 				cost_options.push_back(MakeUnicodeString(cost));
937 			}
938 			break;
939 		case SKILL_FIELD:
940 // 			_skills_list.SetSize(1, menu_skills->size());
941 // 			_skill_cost_list.SetSize(1, menu_skills->size());
942 
943 			for (i = menu_skills->begin(); i != menu_skills->end(); ++i)
944 			{
945 				options.push_back((*i)->GetName());
946 				string cost = NumberToString((*i)->GetSPRequired()) + " SP";
947 				cost_options.push_back(MakeUnicodeString(cost));
948 			}
949 			break;
950 		default:
951 // 			_skills_list.SetSize(1,0);
952 			break;
953 	}
954 
955 	_skills_list.SetOptions(options);
956 	_skill_cost_list.SetOptions(cost_options);
957 
958 	delete menu_skills;
959 	delete battle_skills;
960 	delete all_skills;
961 }
962 
_BuildMenuBattleSkillLists(vector<GlobalSkill * > * skill_list,vector<GlobalSkill * > * field,vector<GlobalSkill * > * battle,vector<GlobalSkill * > * all)963 void SkillsWindow::_BuildMenuBattleSkillLists(vector<GlobalSkill *> *skill_list,
964 		vector<GlobalSkill *> *field, vector<GlobalSkill *> *battle, vector<GlobalSkill *> *all)
965 {
966 	vector<GlobalSkill *>::iterator i;
967 	for (i = skill_list->begin(); i != skill_list->end(); ++i)
968 	{
969 		if ((*i)->IsExecutableInBattle())
970 			battle->push_back(*i);
971 		if ((*i)->IsExecutableInField())
972 			field->push_back(*i);
973 		all->push_back(*i);
974 	}
975 }
976 
977 
Draw()978 void SkillsWindow::Draw() {
979 	MenuWindow::Draw();
980 
981 	//Draw option boxes
982 	_char_select.Draw();
983 	_skills_categories.Draw();
984 	if (_active_box == SKILL_ACTIVE_NONE)
985 		_UpdateSkillList();
986 	_skills_list.Draw();
987 	_skill_cost_list.Draw();
988 }
989 
990 ////////////////////////////////////////////////////////////////////////////////
991 // EquipWindow Class
992 ////////////////////////////////////////////////////////////////////////////////
993 
EquipWindow()994 EquipWindow::EquipWindow() :
995 	_active_box(EQUIP_ACTIVE_NONE)
996 {
997 	// Initialize option boxes
998 	_InitCharSelect();
999 	_InitEquipmentSelect();
1000 	_InitEquipmentList();
1001 }
1002 
1003 
1004 
~EquipWindow()1005 EquipWindow::~EquipWindow() {
1006 }
1007 
1008 
1009 
Activate(bool new_status)1010 void EquipWindow::Activate(bool new_status) {
1011 
1012 	//Activate window and first option box...or deactivate both
1013 	if (new_status) {
1014 		_active_box = EQUIP_ACTIVE_CHAR;
1015 		_char_select.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
1016 	}
1017 	else {
1018 		_active_box = EQUIP_ACTIVE_NONE;
1019 		_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
1020 	}
1021 }
1022 
1023 
1024 
_InitEquipmentList()1025 void EquipWindow::_InitEquipmentList() {
1026 	// Set up the inventory option box
1027 // 	_equip_list.SetCellSize(180.0f, 30.0f);
1028 
1029 	_equip_list.SetPosition(500.0f, 170.0f);
1030 	_equip_list.SetDimensions(400.0f, 360.0f, 1, 255, 1, 6);
1031 	_equip_list.SetTextStyle(TextStyle("text20"));
1032 
1033 	_equip_list.SetCursorOffset(-52.0f, -20.0f);
1034 	_equip_list.SetHorizontalWrapMode(VIDEO_WRAP_MODE_SHIFTED);
1035 	_equip_list.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
1036 	_equip_list.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
1037 	// Update the equipment list
1038 	_UpdateEquipList();
1039 	if (_equip_list.GetNumberOptions() > 0) {
1040 		_equip_list.SetSelection(0);
1041 	}
1042 	// Initially hide the cursor
1043 	_equip_list.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
1044 }
1045 
1046 
1047 
_InitCharSelect()1048 void EquipWindow::_InitCharSelect() {
1049 	//character selection set up
1050 	vector<ustring> options;
1051 	uint32 size = GlobalManager->GetActiveParty()->GetPartySize();
1052 
1053 	_char_select.SetPosition(72.0f, 109.0f);
1054 	_char_select.SetDimensions(360.0f, 432.0f, 1, 4, 1, 4);
1055 	_char_select.SetCursorOffset(-50.0f, -6.0f);
1056 	_char_select.SetTextStyle(TextStyle("text20"));
1057 	_char_select.SetHorizontalWrapMode(VIDEO_WRAP_MODE_SHIFTED);
1058 	_char_select.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
1059 	_char_select.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
1060 
1061 	//Use blank strings....won't be seen anyway
1062 	for (uint32 i = 0; i < size; i++) {
1063 		options.push_back(MakeUnicodeString(" "));
1064 	}
1065 
1066 	//Set options, selection and cursor state
1067 	_char_select.SetOptions(options);
1068 	_char_select.SetSelection(0);
1069 	_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
1070 
1071 } // void EquipWindow::InitCharSelect()
1072 
1073 
1074 
_InitEquipmentSelect()1075 void EquipWindow::_InitEquipmentSelect() {
1076 	//Set params
1077 	_equip_select.SetPosition(680.0f, 145.0f);
1078 	_equip_select.SetDimensions(105.0f, 350.0f, 1, EQUIP_CATEGORY_SIZE, 1, EQUIP_CATEGORY_SIZE);
1079 	_equip_select.SetTextStyle(TextStyle("text20"));
1080 
1081 	_equip_select.SetCursorOffset(-132.0f, -20.0f);
1082 	_equip_select.SetHorizontalWrapMode(VIDEO_WRAP_MODE_SHIFTED);
1083 	_equip_select.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
1084 	_equip_select.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
1085 
1086 	//Set options and default selection
1087 
1088 	_equip_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
1089 	_UpdateEquipList();
1090 	_equip_select.SetSelection(EQUIP_WEAPON);
1091 } // void EquipWindow::_InitEquipmentSelect()
1092 
1093 
1094 
Update()1095 void EquipWindow::Update() {
1096 	// Points to the active option box
1097 	OptionBox *active_option = NULL;
1098 
1099 	//choose correct menu
1100 	switch (_active_box) {
1101 		case EQUIP_ACTIVE_CHAR:
1102 			active_option = &_char_select;
1103 			break;
1104 		case EQUIP_ACTIVE_SELECT:
1105 			active_option = &_equip_select;
1106 			break;
1107 		case EQUIP_ACTIVE_LIST:
1108 			active_option = &_equip_list;
1109 			break;
1110 	}
1111 
1112 	// Handle the appropriate input events
1113 	if (InputManager->ConfirmPress())
1114 	{
1115 		active_option->InputConfirm();
1116 	}
1117 	else if (InputManager->CancelPress())
1118 	{
1119 		active_option->InputCancel();
1120 	}
1121 	else if (InputManager->LeftPress())
1122 	{
1123 		active_option->InputLeft();
1124 	}
1125 	else if (InputManager->RightPress())
1126 	{
1127 		active_option->InputRight();
1128 	}
1129 	else if (InputManager->UpPress())
1130 	{
1131 		active_option->InputUp();
1132 	}
1133 	else if (InputManager->DownPress())
1134 	{
1135 		active_option->InputDown();
1136 	}
1137 
1138 	uint32 event = active_option->GetEvent();
1139 	active_option->Update();
1140 	switch (_active_box) {
1141 	//Choose character
1142 	case EQUIP_ACTIVE_CHAR:
1143 		if (event == VIDEO_OPTION_CONFIRM) {
1144 			_active_box = EQUIP_ACTIVE_SELECT;
1145 			_char_select.SetCursorState(VIDEO_CURSOR_STATE_BLINKING);
1146 			_equip_select.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
1147 			MenuMode::CurrentInstance()->_menu_sounds["confirm"].Play();
1148 		}
1149 		else if (event == VIDEO_OPTION_CANCEL) {
1150 			Activate(false);
1151 			MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
1152 		}
1153 		break;
1154 
1155 	//Choose equipment to replace
1156 	case EQUIP_ACTIVE_SELECT:
1157 		if (event == VIDEO_OPTION_CONFIRM) {
1158 			_active_box = EQUIP_ACTIVE_LIST;
1159 			_UpdateEquipList();
1160 			if (_equip_list.GetNumberOptions() > 0) {
1161 				_equip_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
1162 				_equip_list.SetSelection(0);
1163 				_equip_list.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
1164 				MenuMode::CurrentInstance()->_menu_sounds["confirm"].Play();
1165 			}
1166 			else {
1167 				_active_box = EQUIP_ACTIVE_SELECT;
1168 				MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
1169 			}
1170 		}
1171 		else if (event == VIDEO_OPTION_CANCEL) {
1172 			_active_box = EQUIP_ACTIVE_CHAR;
1173 			_char_select.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
1174 			_equip_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
1175 			MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
1176 		}
1177 		break;
1178 
1179 	//Choose replacement
1180 	case EQUIP_ACTIVE_LIST:
1181 		if (event == VIDEO_OPTION_CONFIRM) {
1182 			GlobalCharacter* ch = dynamic_cast<GlobalCharacter*>(GlobalManager->GetActiveParty()->GetActorAtIndex(_char_select.GetSelection()));
1183 			uint32 id_num;
1184 
1185 			switch ( _equip_select.GetSelection() ) {
1186 			case EQUIP_WEAPON:
1187 			{	GlobalWeapon* wpn = GlobalManager->GetInventoryWeapons()->at(_equip_list.GetSelection());
1188 				if (wpn->GetUsableBy() & ch->GetID()) {
1189 					id_num = wpn->GetID();
1190 					GlobalManager->AddToInventory(ch->EquipWeapon((GlobalWeapon*)GlobalManager->RetrieveFromInventory(id_num)));
1191 				}
1192 				else {
1193 					MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
1194 				}
1195 				break;}
1196 
1197 			case EQUIP_HEADGEAR:
1198 			{	GlobalArmor* hlm = GlobalManager->GetInventoryHeadArmor()->at(_equip_list.GetSelection());
1199 				if (hlm->GetUsableBy() & ch->GetID()) {
1200 					id_num = hlm->GetID();
1201 					GlobalManager->AddToInventory(ch->EquipHeadArmor((GlobalArmor*)GlobalManager->RetrieveFromInventory(id_num)));
1202 				}
1203 				else {
1204 					MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
1205 				}
1206 				break;}
1207 
1208 			case EQUIP_BODYARMOR:
1209 			{	GlobalArmor* arm = GlobalManager->GetInventoryTorsoArmor()->at(_equip_list.GetSelection());
1210 				if (arm->GetUsableBy() & ch->GetID()) {
1211 					id_num = arm->GetID();
1212 					GlobalManager->AddToInventory(ch->EquipTorsoArmor((GlobalArmor*)GlobalManager->RetrieveFromInventory(id_num)));
1213 				}
1214 				else {
1215 					MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
1216 				}
1217 				break;}
1218 
1219 			case EQUIP_OFFHAND:
1220 			{	GlobalArmor* shld = GlobalManager->GetInventoryArmArmor()->at(_equip_list.GetSelection());
1221 				if (shld->GetUsableBy() & ch->GetID()) {
1222 					id_num = shld->GetID();
1223 					GlobalManager->AddToInventory(ch->EquipArmArmor((GlobalArmor*)GlobalManager->RetrieveFromInventory(id_num)));
1224 				}
1225 				else {
1226 					MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
1227 				}
1228 				break;}
1229 
1230 			case EQUIP_LEGGINGS:
1231 			{	GlobalArmor* lgs = GlobalManager->GetInventoryLegArmor()->at(_equip_list.GetSelection());
1232 				if (lgs->GetUsableBy() & ch->GetID()) {
1233 					id_num = lgs->GetID();
1234 					GlobalManager->AddToInventory(ch->EquipLegArmor((GlobalArmor*)GlobalManager->RetrieveFromInventory(id_num)));
1235 				}
1236 				else {
1237 					MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
1238 				}
1239 				break;}
1240 
1241 			default:
1242 				cout << "MENU ERROR: _equip_select.GetSelection value is invalid: " << _equip_select.GetSelection() << endl;
1243 				break;
1244 			} // switch _equip_select.GetSelection()
1245 
1246 			_active_box = EQUIP_ACTIVE_SELECT;
1247 			_equip_list.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
1248 			_equip_select.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
1249 			MenuMode::CurrentInstance()->_menu_sounds["confirm"].Play();
1250 		} // if VIDEO_OPTION_CONFIRM
1251 		else if (event == VIDEO_OPTION_CANCEL) {
1252 			_active_box = EQUIP_ACTIVE_SELECT;
1253 			MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
1254 			_equip_list.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
1255 			_equip_select.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
1256 		} // else if VIDEO_OPTION_CANCEL
1257 		break;
1258 	} // switch _active_box
1259 
1260 	_UpdateEquipList();
1261 } // void EquipWindow::Update()
1262 
1263 
1264 
_UpdateEquipList()1265 void EquipWindow::_UpdateEquipList() {
1266 	GlobalCharacter* ch = dynamic_cast<GlobalCharacter*>(GlobalManager->GetActiveParty()->GetActorAtIndex(_char_select.GetSelection()));
1267 	std::vector<ustring> options;
1268 
1269 	if (_active_box == EQUIP_ACTIVE_LIST) {
1270 		uint32 gearsize = 0;
1271 //		vector<hoa_global::GlobalWeapon*> weapons;
1272 //		vector<hoa_global::GlobalArmor*> armor;
1273 
1274 		switch (_equip_select.GetSelection()) {
1275 			case EQUIP_WEAPON:
1276 				gearsize = GlobalManager->GetInventoryWeapons()->size();
1277 
1278 				for (uint32 j = 0; j < gearsize; j++) {
1279 					options.push_back(GlobalManager->GetInventoryWeapons()->at(j)->GetName());
1280 				}
1281 
1282 				break;
1283 
1284 			case EQUIP_HEADGEAR:
1285 				gearsize = GlobalManager->GetInventoryHeadArmor()->size();
1286 
1287 				for (uint32 j = 0; j < gearsize; j++) {
1288 					options.push_back(GlobalManager->GetInventoryHeadArmor()->at(j)->GetName());
1289 				}
1290 
1291 				break;
1292 
1293 			case EQUIP_BODYARMOR:
1294 				gearsize = GlobalManager->GetInventoryTorsoArmor()->size();
1295 
1296 				for (uint32 j = 0; j < gearsize; j++) {
1297 					options.push_back(GlobalManager->GetInventoryTorsoArmor()->at(j)->GetName());
1298 				}
1299 
1300 				break;
1301 
1302 			case EQUIP_OFFHAND:
1303 				gearsize = GlobalManager->GetInventoryArmArmor()->size();
1304 
1305 				for (uint32 j = 0; j < gearsize; j++) {
1306 					options.push_back(GlobalManager->GetInventoryArmArmor()->at(j)->GetName());
1307 				}
1308 
1309 				break;
1310 
1311 			case EQUIP_LEGGINGS:
1312 				gearsize = GlobalManager->GetInventoryLegArmor()->size();
1313 
1314 				for (uint32 j = 0; j < gearsize; j++) {
1315 					options.push_back(GlobalManager->GetInventoryLegArmor()->at(j)->GetName());
1316 				}
1317 
1318 				break;
1319 		} // switch
1320 // 		_equip_list.SetSize(1, gearsize);
1321 		_equip_list.SetOptions(options);
1322 	} // if EQUIP_ACTIVE_LIST
1323 
1324 	else {
1325 		// First, update the IMAGES of the equipped items
1326 		_equip_images.clear();
1327 		StillImage i;
1328 
1329 		i.Load(ch->GetWeaponEquipped()->GetIconImage().GetFilename(), 60, 60);
1330 		_equip_images.push_back(i);
1331 
1332 		i.Load(ch->GetHeadArmorEquipped()->GetIconImage().GetFilename(), 60, 60);
1333 		_equip_images.push_back(i);
1334 
1335 		i.Load(ch->GetTorsoArmorEquipped()->GetIconImage().GetFilename(), 60, 60);
1336 		_equip_images.push_back(i);
1337 
1338 		i.Load(ch->GetArmArmorEquipped()->GetIconImage().GetFilename(), 60, 60);
1339 		_equip_images.push_back(i);
1340 
1341 		i.Load(ch->GetLegArmorEquipped()->GetIconImage().GetFilename(), 60, 60);
1342 		_equip_images.push_back(i);
1343 
1344 		// Now, update the NAMES of the equipped items
1345 
1346 		options.push_back(ch->GetWeaponEquipped()->GetName());
1347 		options.push_back(ch->GetHeadArmorEquipped()->GetName());
1348 		options.push_back(ch->GetTorsoArmorEquipped()->GetName());
1349 		options.push_back(ch->GetArmArmorEquipped()->GetName());
1350 		options.push_back(ch->GetLegArmorEquipped()->GetName());
1351 
1352 // 		_equip_select.SetSize(1, 5);
1353 		_equip_select.SetOptions(options);
1354 	}
1355 
1356 } // void EquipWindow::UpdateEquipList()
1357 
1358 
1359 
Draw()1360 void EquipWindow::Draw() {
1361 	MenuWindow::Draw();
1362 	_UpdateEquipList();
1363 
1364 	//Draw option boxes
1365 	_char_select.Draw();
1366 
1367 	if (_active_box == EQUIP_ACTIVE_LIST) {
1368 		_equip_list.Draw();
1369 		VideoManager->Move(660.0f, 135.0f);
1370 		VideoManager->SetDrawFlags(VIDEO_X_CENTER, VIDEO_Y_CENTER, 0);
1371 		switch (_equip_select.GetSelection()) {
1372 			case EQUIP_WEAPON:
1373 				VideoManager->Text()->Draw(UTranslate("Weapons"));
1374 				break;
1375 			case EQUIP_HEADGEAR:
1376 				VideoManager->Text()->Draw(UTranslate("Headgear"));
1377 				break;
1378 			case EQUIP_BODYARMOR:
1379 				VideoManager->Text()->Draw(UTranslate("Body Armor"));
1380 				break;
1381 			case EQUIP_OFFHAND:
1382 				VideoManager->Text()->Draw(UTranslate("Offhand"));
1383 				break;
1384 			case EQUIP_LEGGINGS:
1385 				VideoManager->Text()->Draw(UTranslate("Leggings"));
1386 				break;
1387 		}
1388 	}
1389 	else {
1390 		_equip_select.Draw();
1391 
1392 		//FIX ME: Use XML tags for formatting option boxes
1393 		VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_TOP, 0);
1394 		VideoManager->Move(450.0f, 170.0f);
1395 		VideoManager->Text()->Draw(UTranslate("Weapon"));
1396 		VideoManager->MoveRelative(0.0f, 70.0f);
1397 		VideoManager->Text()->Draw(UTranslate("Headgear"));
1398 		VideoManager->MoveRelative(0.0f, 70.0f);
1399 		VideoManager->Text()->Draw(UTranslate("Body Armor"));
1400 		VideoManager->MoveRelative(0.0f, 70.0f);
1401 		VideoManager->Text()->Draw(UTranslate("Offhand"));
1402 		VideoManager->MoveRelative(0.0f, 70.0f);
1403 		VideoManager->Text()->Draw(UTranslate("Leggings"));
1404 
1405 		VideoManager->MoveRelative(150.0f, -370.0f);
1406 
1407 		for (uint32 i = 0; i < _equip_images.size(); i++) {
1408 			VideoManager->MoveRelative(0.0f, 70.0f);
1409 			_equip_images[i].Draw();
1410 		}
1411 	}
1412 
1413 } // void EquipWindow::Draw()
1414 
1415 
FormationWindow()1416 FormationWindow::FormationWindow() : _active_box(FORM_ACTIVE_NONE) {
1417 	_InitCharSelect();
1418 }
1419 
1420 
~FormationWindow()1421 FormationWindow::~FormationWindow() {
1422 }
1423 
1424 
_InitCharSelect()1425 void FormationWindow::_InitCharSelect() {
1426 	//character selection set up
1427 	std::vector<ustring> options;
1428 	uint32 size = GlobalManager->GetActiveParty()->GetPartySize();
1429 
1430 	_char_select.SetPosition(72.0f, 109.0f);
1431 	_char_select.SetDimensions(360.0f, 432.0f, 1, 4, 1, 4);
1432 	_char_select.SetCursorOffset(-50.0f, -6.0f);
1433 	_char_select.SetTextStyle(TextStyle("text20"));
1434 	_char_select.SetHorizontalWrapMode(VIDEO_WRAP_MODE_SHIFTED);
1435 	_char_select.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
1436 	_char_select.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
1437 
1438 	_second_char_select.SetPosition(72.0f, 109.0f);
1439 	_second_char_select.SetDimensions(360.0f, 432.0f, 1, 4, 1, 4);
1440 	_second_char_select.SetCursorOffset(-50.0f, -6.0f);
1441 	_second_char_select.SetTextStyle(TextStyle("text20"));
1442 	_second_char_select.SetHorizontalWrapMode(VIDEO_WRAP_MODE_SHIFTED);
1443 	_second_char_select.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
1444 	_second_char_select.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
1445 
1446 
1447 	// Use blank string so cursor can point somewhere
1448 	for (uint32 i = 0; i < size; i++) {
1449 		options.push_back(MakeUnicodeString(" "));
1450 	}
1451 
1452 	_char_select.SetOptions(options);
1453 	_char_select.SetSelection(0);
1454 	_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
1455 
1456 	_second_char_select.SetOptions(options);
1457 	_second_char_select.SetSelection(0);
1458 	_second_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
1459 
1460 }
1461 
1462 
Update()1463 void FormationWindow::Update() {
1464 	// Points to the active option box
1465 	OptionBox *active_option = NULL;
1466 
1467 	//choose correct menu
1468 	switch (_active_box) {
1469 		case FORM_ACTIVE_CHAR:
1470 			active_option = &_char_select;
1471 			break;
1472 		case FORM_ACTIVE_SECOND:
1473 			active_option = &_second_char_select;
1474 			break;
1475 	}
1476 
1477 	// Handle the appropriate input events
1478 	if (InputManager->ConfirmPress())
1479 	{
1480 		active_option->InputConfirm();
1481 	}
1482 	else if (InputManager->CancelPress())
1483 	{
1484 		active_option->InputCancel();
1485 	}
1486 	else if (InputManager->LeftPress())
1487 	{
1488 		active_option->InputLeft();
1489 	}
1490 	else if (InputManager->RightPress())
1491 	{
1492 		active_option->InputRight();
1493 	}
1494 	else if (InputManager->UpPress())
1495 	{
1496 		active_option->InputUp();
1497 	}
1498 	else if (InputManager->DownPress())
1499 	{
1500 		active_option->InputDown();
1501 	}
1502 
1503 	uint32 event = active_option->GetEvent();
1504 	active_option->Update();
1505 
1506 	switch (_active_box) {
1507 		case FORM_ACTIVE_CHAR:
1508 			if (event == VIDEO_OPTION_CONFIRM) {
1509 				_active_box = FORM_ACTIVE_SECOND;
1510 				_char_select.SetCursorState(VIDEO_CURSOR_STATE_BLINKING);
1511 				_second_char_select.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
1512 				MenuMode::CurrentInstance()->_menu_sounds["confirm"].Play();
1513 			}
1514 			else if (event == VIDEO_OPTION_CANCEL) {
1515 				Activate(false);
1516 				MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
1517 			}
1518 			break;
1519 
1520 		case FORM_ACTIVE_SECOND:
1521 			if (event == VIDEO_OPTION_CONFIRM) {
1522 				// TODO: Implement Character Switch
1523 				_active_box = FORM_ACTIVE_CHAR;
1524 				_char_select.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
1525 				_second_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
1526 			}
1527 			else if (event == VIDEO_OPTION_CANCEL) {
1528 				_active_box = FORM_ACTIVE_CHAR;
1529 				_char_select.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
1530 				_second_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
1531 				MenuMode::CurrentInstance()->_menu_sounds["cancel"].Play();
1532 			}
1533 			break;
1534 	} // switch
1535 	_char_select.Update();
1536 }
1537 
1538 
Draw()1539 void FormationWindow::Draw() {
1540 	MenuWindow::Draw();
1541 	_char_select.Draw();
1542 	_second_char_select.Draw();
1543 }
1544 
1545 
Activate(bool new_status)1546 void FormationWindow::Activate(bool new_status) {
1547 	if (new_status) {
1548 		_active_box = FORM_ACTIVE_CHAR;
1549 		_char_select.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
1550 	}
1551 	else {
1552 		_active_box = FORM_ACTIVE_NONE;
1553 		_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
1554 		_second_char_select.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
1555 	}
1556 }
1557 
1558 
1559 } // namespace private_menu
1560 
1561 
MessageWindow(const ustring & message,float w,float h)1562 MessageWindow::MessageWindow(const ustring &message, float w, float h) :
1563 	_message(message)
1564 {
1565 	float start_x = (1024 - w) / 2;
1566 	float start_y = (768 - h) / 2;
1567 
1568 	MenuWindow::Create(w, h);
1569 	MenuWindow::SetPosition(start_x, start_y);
1570 	MenuWindow::Show();
1571 
1572 	_textbox.SetPosition(30, 5);
1573 	_textbox.SetDimensions(w, h);
1574 	_textbox.SetTextStyle(TextStyle("text22"));
1575 	_textbox.SetDisplayMode(VIDEO_TEXT_INSTANT);
1576 	_textbox.SetTextAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
1577 	_textbox.SetDisplayText(_message);
1578 	_textbox.SetOwner(this);
1579 }
1580 
~MessageWindow()1581 MessageWindow::~MessageWindow()
1582 {
1583 	MenuWindow::Destroy();
1584 }
1585 
Draw()1586 void MessageWindow::Draw()
1587 {
1588 	MenuWindow::Draw();
1589 	_textbox.Draw();
1590 }
1591 
1592 } // namespace hoa_menu
1593