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_root.cpp
12 *** \author  Tyler Olsen, roots@allacrost.org
13 *** \brief   Source file for root interface of shop mode
14 *** ***************************************************************************/
15 
16 #include <iostream>
17 
18 #include "utils.h"
19 
20 #include "audio.h"
21 #include "video.h"
22 #include "input.h"
23 #include "mode_manager.h"
24 #include "system.h"
25 
26 #include "global.h"
27 
28 #include "shop.h"
29 #include "shop_root.h"
30 
31 using namespace std;
32 
33 using namespace hoa_utils;
34 using namespace hoa_audio;
35 using namespace hoa_video;
36 using namespace hoa_gui;
37 using namespace hoa_input;
38 using namespace hoa_mode_manager;
39 using namespace hoa_system;
40 using namespace hoa_global;
41 
42 namespace hoa_shop {
43 
44 namespace private_shop {
45 
46 // The maximum number of category icons + text that can be displayed in a single row
47 const uint8 MAX_CATEGORY_ROW_SIZE = 4;
48 
49 // *****************************************************************************
50 // ***** CategoryDrawData class methods
51 // *****************************************************************************
52 
ComputeCoordinates(uint8 number_categories)53 void CategoryDrawData::ComputeCoordinates(uint8 number_categories) {
54 	if (number_categories > GLOBAL_OBJECT_TOTAL) {
55 		IF_PRINT_WARNING(SHOP_DEBUG) << "invalid argument value: " << number_categories << endl;
56 		return;
57 	}
58 
59 	// ---------- (1): Determine the number of entries in each category row
60 	if (number_categories <= MAX_CATEGORY_ROW_SIZE) {
61 		first_row_num = number_categories;
62 		second_row_num = 0;
63 	}
64 	else {
65 		first_row_num = MAX_CATEGORY_ROW_SIZE;
66 		second_row_num = number_categories - first_row_num;
67 	}
68 
69 	// ---------- (2): Determine the y position in each category row
70 	if (second_row_num != 0) { // then there are two rows of categories to draw
71 		first_row_y = 420.0f;
72 		second_row_y = 320.0f;
73 	}
74 	else {
75 		first_row_y = 370.0f;
76 		second_row_y = first_row_y;
77 	}
78 
79 	// ---------- (3): Determine the x position of each category row
80 	switch (first_row_num) {
81 		case 1:
82 			first_row_x = 512.0f; // Horizontal center of screen
83 			break;
84 		case 2:
85 			first_row_x = 437.0f; // The delta between icons when drawn is 150.0f, so move the draw cursor by half that amount
86 			break;
87 		case 3:
88 			first_row_x = 362.0f;
89 			break;
90 		case 4:
91 			first_row_x = 287.0f;
92 			break;
93 	}
94 	switch (second_row_num) {
95 		case 1:
96 			second_row_x = 512.0f;
97 			break;
98 		case 2:
99 			second_row_x = 437.0f;
100 			break;
101 		case 3:
102 			second_row_x = 362.0f;
103 			break;
104 		case 4:
105 			second_row_x = 287.0f;
106 			break;
107 	}
108 } // void CategoryDrawData::ComputeCoordinates(uint8 number_categories)
109 
110 // *****************************************************************************
111 // ***** RootInterface class methods
112 // *****************************************************************************
113 
RootInterface()114 RootInterface::RootInterface() {
115 	// Initialize text properties and set default text where appropriate
116 	_shop_name.SetStyle(TextStyle("title28"));
117 	_shop_name.SetText(UTranslate("Shop Name")); // This default name should be overwritten
118 
119 	_buy_price_text.SetStyle(TextStyle("text22"));
120 	_buy_price_text.SetText(UTranslate("Buy prices"));
121 	_sell_price_text.SetStyle(TextStyle("text22"));
122 	_sell_price_text.SetText(UTranslate("Sell prices"));
123 
124 	_greeting_text.SetOwner(ShopMode::CurrentInstance()->GetBottomWindow());
125 	_greeting_text.SetPosition(40.0f, 100.0f);
126 	_greeting_text.SetDimensions(600.0f, 50.0f);
127 	_greeting_text.SetTextStyle(TextStyle("text22"));
128 	_greeting_text.SetDisplayMode(VIDEO_TEXT_INSTANT);
129 	_greeting_text.SetTextAlignment(VIDEO_X_LEFT, VIDEO_Y_TOP);
130 	_greeting_text.SetDisplayText(UTranslate("\"Welcome! Take a look around.\"")); // Default greeting, should usually be overwritten
131 }
132 
133 
134 
Initialize()135 void RootInterface::Initialize() {
136 	// ---------- (1): Create the price level graphics
137 	// Holds the number of stars to display that represent the price levels
138 	int8 num_buy_stars = 0;
139 	int8 num_sell_stars = 0;
140 
141 	// Determine the number of stars based on the price level
142 	switch (ShopMode::CurrentInstance()->GetBuyPriceLevel()) {
143 		case SHOP_PRICE_VERY_GOOD:
144 			num_buy_stars = 5;
145 			break;
146 		case SHOP_PRICE_GOOD:
147 			num_buy_stars = 4;
148 			break;
149 		case SHOP_PRICE_STANDARD:
150 			num_buy_stars = 3;
151 			break;
152 		case SHOP_PRICE_POOR:
153 			num_buy_stars = 2;
154 			break;
155 		case SHOP_PRICE_VERY_POOR:
156 			num_buy_stars = 1;
157 			break;
158 		default:
159 			IF_PRINT_WARNING(SHOP_DEBUG) << "invalid buy level argument: " << ShopMode::CurrentInstance()->GetBuyPriceLevel() << endl;
160 			break;
161 	}
162 
163 	switch (ShopMode::CurrentInstance()->GetSellPriceLevel()) {
164 		case SHOP_PRICE_VERY_GOOD:
165 			num_sell_stars = 5;
166 			break;
167 		case SHOP_PRICE_GOOD:
168 			num_sell_stars = 4;
169 			break;
170 		case SHOP_PRICE_STANDARD:
171 			num_sell_stars = 3;
172 			break;
173 		case SHOP_PRICE_POOR:
174 			num_sell_stars = 2;
175 			break;
176 		case SHOP_PRICE_VERY_POOR:
177 			num_sell_stars = 1;
178 			break;
179 		default:
180 			IF_PRINT_WARNING(SHOP_DEBUG) << "invalid sell level argument: " << ShopMode::CurrentInstance()->GetSellPriceLevel() << endl;
181 			break;
182 	}
183 
184 	// Star images used to construct the composite star rating (30x30 pixel size)
185 	StillImage star, gray_star;
186 	star = *(ShopMode::CurrentInstance()->Media()->GetStarIcon());
187 	gray_star = star;
188 	gray_star.EnableGrayScale();
189 
190 	// Finally, construct the composite images with the correct star rating
191 	_buy_price_rating.SetDimensions(200.0f, 30.0f);
192 	_sell_price_rating.SetDimensions(200.0f, 30.0f);
193 
194 	float offset = 0.0f;
195 	for (uint8 count = 5; count > 0; count--) {
196 		if (num_buy_stars > 0) {
197 			_buy_price_rating.AddImage(star, offset, 0.0f);
198 		}
199 		else {
200 			_buy_price_rating.AddImage(gray_star, offset, 0.0f);
201 		}
202 
203 		num_buy_stars--;
204 		offset += 40.0f;
205 	}
206 
207 	offset = 0.0f;
208 	for (uint8 count = 5; count > 0; count--, num_sell_stars--) {
209 		if (num_sell_stars > 0) {
210 			_sell_price_rating.AddImage(star, offset, 0.0f);
211 		}
212 		else {
213 			_sell_price_rating.AddImage(gray_star, offset, 0.0f);
214 		}
215 
216 		num_buy_stars--;
217 		offset += 40.0f;
218 	}
219 
220 	// ---------- (2): Construct category name text and graphics and determine category draw coordinates
221 	// Determine the number of names and icons of categories to load
222 	uint32 number_categories = ShopMode::CurrentInstance()->Media()->GetSaleCategoryNames()->size();
223 	if (number_categories > 1) // If multiple categories are available, remove one because we don't want to show the "all" category
224 		number_categories--;
225 
226 	TextStyle name_style("text22");
227 	for (uint32 i = 0; i < number_categories; i++) {
228 		_category_names.push_back(TextImage(ShopMode::CurrentInstance()->Media()->GetSaleCategoryNames()->at(i), name_style));
229 		_category_icons.push_back(ShopMode::CurrentInstance()->Media()->GetSaleCategoryIcons()->at(i));
230 	}
231 
232 	_category_draw_data.ComputeCoordinates(_category_icons.size());
233 } // void RootInterface::Initialize()
234 
235 
236 
Update()237 void RootInterface::Update() {
238 	_greeting_text.Update();
239 }
240 
241 
242 
Draw()243 void RootInterface::Draw() {
244 	VideoManager->SetDrawFlags(VIDEO_X_CENTER, VIDEO_Y_TOP, 0);
245 
246 	// Middle window: draw shop's name at the top
247 	VideoManager->Move(512.0f, 580.0f);
248 	_shop_name.Draw();
249 
250 	// Middle window: below the shop name draw the pricing text and rating image
251 	VideoManager->MoveRelative(-140.0f, -60.0f);
252 	_buy_price_text.Draw();
253 	VideoManager->MoveRelative(280.0f, 0.0f);
254 	_sell_price_text.Draw();
255 
256 	VideoManager->MoveRelative(-280.0f, -40.0f);
257 	_buy_price_rating.Draw();
258 	VideoManager->MoveRelative(280.0f, 0.0f);
259 	_sell_price_rating.Draw();
260 
261 	// Middle window: below the pricing text/image draw the category icons and text in one or two rows
262 	VideoManager->Move(_category_draw_data.first_row_x, _category_draw_data.first_row_y);
263 	for (uint8 i = 0; i < _category_draw_data.first_row_num; i++) {
264 		_category_icons[i].Draw();
265 		VideoManager->MoveRelative(0.0f, -60.0f);
266 		_category_names[i].Draw();
267 		VideoManager->MoveRelative(150.0f, 60.0f);
268 	}
269 
270 	VideoManager->Move(_category_draw_data.second_row_x, _category_draw_data.second_row_y);
271 	for (uint8 i = 0; i < _category_draw_data.second_row_num; i++) {
272 		_category_icons[i + MAX_CATEGORY_ROW_SIZE].Draw();
273 		VideoManager->MoveRelative(0.0f, -60.0f);
274 		_category_names[i +MAX_CATEGORY_ROW_SIZE].Draw();
275 		VideoManager->MoveRelative(150.0f, 60.0f);
276 	}
277 
278 	// Bottom window: draw the greeting text
279 	_greeting_text.Draw();
280 }
281 
282 
283 
SetShopName(hoa_utils::ustring name)284 void RootInterface::SetShopName(hoa_utils::ustring name) {
285 	_shop_name.SetText(name);
286 }
287 
288 
289 
SetGreetingText(hoa_utils::ustring greeting)290 void RootInterface::SetGreetingText(hoa_utils::ustring greeting) {
291 	_greeting_text.SetDisplayText(greeting);
292 }
293 
294 } // namespace private_shop
295 
296 } // namespace hoa_shop
297