1 /*
2  * Seven Kingdoms: Ancient Adversaries
3  *
4  * Copyright 1997,1998 Enlight Software Ltd.
5  *
6  * This program 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 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 //Filename    : OR_TECH.CPP
22 //Description : Technology Report
23 
24 #include <OVGA.h>
25 #include <vga_util.h>
26 #include <OFONT.h>
27 #include <OIMGRES.h>
28 #include <OVBROWIF.h>
29 #include <OBUTTON.h>
30 #include <OTECHRES.h>
31 #include <OGODRES.h>
32 #include <ORACERES.h>
33 #include <ONATION.h>
34 #include <OU_GOD.h>
35 #include <OINFO.h>
36 #include "gettext.h"
37 
38 //------------- Define coordinations -----------//
39 
40 enum { TECH_BROWSE_X1 = ZOOM_X1+6,
41 		 TECH_BROWSE_Y1 = ZOOM_Y1+6,
42 		 TECH_BROWSE_X2 = ZOOM_X2-6,
43 		 TECH_BROWSE_Y2 = TECH_BROWSE_Y1+220
44 	  };
45 
46 enum { SCROLL_X1 = ZOOM_X1+6,
47 		 SCROLL_Y1 = TECH_BROWSE_Y2+6,
48 		 SCROLL_X2 = ZOOM_X2-6,
49 		 SCROLL_Y2 = SCROLL_Y1+80
50 	  };
51 
52 enum { GOD_BROWSE_X1 = ZOOM_X1+6,
53 		 GOD_BROWSE_Y1 = SCROLL_Y2+6,
54 		 GOD_BROWSE_X2 = ZOOM_X2-6,
55 		 GOD_BROWSE_Y2 = ZOOM_Y2-6
56 	  };
57 
58 //----------- Define static variables ----------//
59 
60 static VBrowseIF browse_tech, browse_god;
61 
62 //----------- Define static functions ----------//
63 
64 static int  tech_filter(int recNo=0);
65 static int  god_filter(int recNo=0);
66 static void put_tech_rec(int recNo, int x, int y, int refreshFlag);
67 static void put_god_rec(int recNo, int x, int y, int refreshFlag);
68 static void disp_owned_scroll();
69 static void disp_scroll(int x, int y, int raceId);
70 static void put_heading(char justify, int x1, int y1, int x2, int y2, const char *textPtr);
71 
72 #define J_L Font::LEFT_JUSTIFY
73 #define J_C Font::CENTER_JUSTIFY
74 #define J_R Font::RIGHT_JUSTIFY
75 
76 //--------- Begin of function Info::disp_tech ---------//
77 //
disp_tech(int refreshFlag)78 void Info::disp_tech(int refreshFlag)
79 {
80 	//-------- display the technology browser ---------//
81 
82 	int x=TECH_BROWSE_X1+9;
83 	int y=TECH_BROWSE_Y1+4;
84 
85 	vga_back.d3_panel_up(TECH_BROWSE_X1, TECH_BROWSE_Y1, TECH_BROWSE_X2, TECH_BROWSE_Y1+32 );
86 
87 	put_heading( J_L, x, y, x+160, y+29, _("Technology") );
88 
89 #if(defined(SPANISH))
90 	font_san.put( x+160, y   , "Version" );
91 	font_san.put( x+160, y+13, "Present");
92 
93 	font_san.put( x+245, y   , "Version" );
94 	font_san.put( x+230, y+13, "Researching");
95 
96 	font_san.put( x+320, y+7, "Research Progress" );
97 
98 	font_san.put( x+460, y   , "Tower of" );
99 	font_san.put( x+468, y+13, "Science" );
100 #elif(defined(FRENCH))
101 	font_san.put( x+160, y   , "Cat�gorie" );
102 	font_san.put( x+160, y+13, "Actuelle" );
103 
104 	font_san.put( x+230, y   , "Cat�gorie" );
105 	font_san.put( x+230, y+13, "Recherch�e" );
106 
107 	font_san.put( x+320, y,    "Etat de la" );
108 	font_san.put( x+320, y+13, "Recherche");
109 
110 	font_san.put( x+460, y   , "Tour du" );
111 	font_san.put( x+462, y+13, "Savoir" );
112 #else
113 	// German and US
114 	put_heading( J_L, x+160, y, x+230, y+29, _("Present Version") );
115 	put_heading( J_L, x+230, y, x+320, y+29, _("Researching Version") );
116 	put_heading( J_L, x+320, y, x+460, y+29, _("Research Progress") );
117 	put_heading( J_L, x+460, y, TECH_BROWSE_X2-20, y+29, _("Tower of Science") );
118 #endif
119 
120 	if( refreshFlag == INFO_REPAINT )
121 	{
122 		browse_tech.init( TECH_BROWSE_X1, TECH_BROWSE_Y1+34, TECH_BROWSE_X2, TECH_BROWSE_Y2,
123 								0, 22, tech_filter(), put_tech_rec, 1 );
124 
125 		browse_tech.open(browse_tech_recno);
126 	}
127 	else
128 	{
129 		browse_tech.paint();
130 		browse_tech.open(browse_tech_recno, tech_filter());
131 	}
132 
133 	//----- display the list of acquired scrolls of power ----//
134 
135 	disp_owned_scroll();
136 
137 	//-------- display the god unit browser ---------//
138 
139 	x=GOD_BROWSE_X1+9;
140 	y=GOD_BROWSE_Y1+4;
141 
142 	vga_back.d3_panel_up(GOD_BROWSE_X1, GOD_BROWSE_Y1, GOD_BROWSE_X2, GOD_BROWSE_Y1+20 );
143 
144 	font_san.put( x	 , y, _("Greater Being") );
145 	font_san.put( x+300, y, _("Hit Points") );
146 
147 	if( refreshFlag == INFO_REPAINT )
148 	{
149 		browse_god.init( GOD_BROWSE_X1, GOD_BROWSE_Y1+22, GOD_BROWSE_X2, GOD_BROWSE_Y2,
150 							  0, 22, god_filter(), put_god_rec, 1 );
151 
152 		browse_god.open(browse_god_recno);
153 	}
154 	else
155 	{
156 		browse_god.paint();
157 		browse_god.open(browse_god_recno, god_filter());
158 	}
159 }
160 //----------- End of function Info::disp_tech -----------//
161 
162 
163 //--------- Begin of function Info::detect_tech ---------//
164 //
detect_tech()165 void Info::detect_tech()
166 {
167 	if( browse_tech.detect() )
168 		browse_tech_recno = browse_tech.recno();
169 
170 	if( browse_god.detect() )
171 	{
172 		browse_god_recno = browse_god.recno();
173 
174 		if( browse_god.double_click )
175 		{
176 			Unit* unitPtr = unit_array[ god_filter(browse_god.recno()) ];
177 
178 			world.go_loc( unitPtr->next_x_loc(), unitPtr->next_y_loc(), 1 );
179 		}
180 	}
181 }
182 //----------- End of function Info::detect_tech -----------//
183 
184 
185 //-------- Begin of static function tech_filter --------//
186 //
187 // This function has dual purpose :
188 //
189 // 1. when <int> recNo is not given :
190 //    - return the total no. of firms of this nation
191 //
192 // 2. when <int> recNo is given :
193 //    - return the firm recno in firm_array of the given recno.
194 //
tech_filter(int recNo)195 static int tech_filter(int recNo)
196 {
197 	int 		 techCount=0;
198 	TechInfo* techInfo;
199 
200 	for( int techId=tech_res.tech_count ; techId>0 ; techId-- )
201 	{
202 		techInfo = tech_res[techId];
203 
204 		if( techInfo->is_nation_researching(info.viewing_nation_recno) ||
205 			 techInfo->get_nation_tech_level(info.viewing_nation_recno) > 0 )
206 		{
207 			techCount++;
208 		}
209 
210 		if( recNo && techCount==recNo )
211 			return techId;
212 	}
213 
214 	err_when( recNo );   // the recNo is not found, it is out of range
215 
216 	return techCount;
217 }
218 //----------- End of static function tech_filter -----------//
219 
220 
221 //-------- Begin of static function god_filter --------//
222 //
223 // This function has dual purpose :
224 //
225 // 1. when <int> recNo is not given :
226 //    - return the total no. of firms of this nation
227 //
228 // 2. when <int> recNo is given :
229 //    - return the firm recno in firm_array of the given recno.
230 //
god_filter(int recNo)231 static int god_filter(int recNo)
232 {
233 	int 	godCount=0, totalUnit=unit_array.size();
234 	Unit* unitPtr;
235 
236 	for( int i=1 ; i<=totalUnit ; i++ )
237 	{
238 		if( unit_array.is_deleted(i) )
239 			continue;
240 
241 		unitPtr = unit_array[i];
242 
243 		if( unitPtr->nation_recno == info.viewing_nation_recno &&
244 			 unit_res[ unitPtr->unit_id ]->unit_class == UNIT_CLASS_GOD )
245 		{
246 			godCount++;
247 		}
248 
249 		if( recNo && godCount==recNo )
250 			return i;
251 	}
252 
253 	err_when( recNo );   // the recNo is not found, it is out of range
254 
255 	return godCount;
256 }
257 //----------- End of static function god_filter -----------//
258 
259 
260 //-------- Begin of static function put_tech_rec --------//
261 //
put_tech_rec(int recNo,int x,int y,int refreshFlag)262 static void put_tech_rec(int recNo, int x, int y, int refreshFlag)
263 {
264 	int   	 techId   = tech_filter(recNo);
265 	TechInfo* techInfo = tech_res[techId];
266 
267 	//---------- display bitmap ----------//
268 
269 	x+=3;
270 	y+=3;
271 
272 	vga_back.put_bitmap( x, y-2, techInfo->tech_small_icon() );
273 
274 	//----------- display info ----------//
275 
276 	y+=2;
277 
278 	int curLevel = techInfo->get_nation_tech_level(info.viewing_nation_recno);
279 
280 	font_san.put( x+28 , y, techInfo->tech_des() );
281 
282 	if( curLevel > 0 )
283 		font_san.put( x+180, y, misc.roman_number(curLevel) );
284 
285 	//----- if the nation is researching this technology -----//
286 
287 	int isResearching = techInfo->is_nation_researching(info.viewing_nation_recno);
288 
289 	if( isResearching )
290 	{
291 		err_when( curLevel >= techInfo->max_tech_level );
292 
293 		font_san.put( x+260, y, misc.roman_number(curLevel+1) );
294 		font_san.put( x+480, y, isResearching );		//isResearching tells the no. of towers of science researching this technology
295 
296 		//----- display the research progress bar -----//
297 
298 		vga_util.d3_panel_down( x+320, y-2, x+440, y+14 );
299 		vga_back.indicator( x+321, y-1, x+439, y+13, techInfo->get_progress(info.viewing_nation_recno), (float)100, VGA_GRAY );
300 	}
301 }
302 //----------- End of static function put_tech_rec -----------//
303 
304 
305 //-------- Begin of static function put_god_rec --------//
306 //
put_god_rec(int recNo,int x,int y,int refreshFlag)307 static void put_god_rec(int recNo, int x, int y, int refreshFlag)
308 {
309 	UnitGod* unitGod = (UnitGod*) unit_array[ god_filter(recNo) ];
310 
311 	err_when( unit_res[unitGod->unit_id]->unit_class != UNIT_CLASS_GOD );
312 
313 	//----------- display info ----------//
314 
315 	x+=3;
316 	y+=5;
317 
318 	font_san.put( x, y, _(unit_res[unitGod->unit_id]->name) );
319 
320 	//--------- display hit points -----------//
321 
322 	String str;
323 
324 	str  = (int) unitGod->hit_points;
325 	str += "/";
326 	str += unitGod->max_hit_points;
327 
328 	font_san.put( x+300, y, str );
329 }
330 //----------- End of static function put_god_rec -----------//
331 
332 
333 //-------- Begin of static function disp_scroll --------//
334 //
disp_scroll(int x,int y,int raceId)335 static void disp_scroll(int x, int y, int raceId)
336 {
337 	char iconName[]="SCROLL-0";
338 
339 	iconName[7] = race_res[raceId]->code[0];
340 
341 	image_spict.put_back( x, y, iconName );
342 }
343 //----------- End of static function disp_scroll -----------//
344 
345 
346 //-------- Begin of static function disp_owned_scroll --------//
347 //
disp_owned_scroll()348 static void disp_owned_scroll()
349 {
350 	vga_util.d3_panel_down( SCROLL_X1, SCROLL_Y1, SCROLL_X2, SCROLL_Y2 );
351 
352 	//------ count the number of acquired scrolls ------//
353 
354 	Nation* nationPtr = nation_array[info.viewing_nation_recno];
355 	int scrollCount=0;
356 
357 	int i;
358 	for( i=0 ; i<MAX_RACE ; i++ )
359 	{
360 		if( nationPtr->know_base_array[i] )
361 			scrollCount++;
362 	}
363 
364 	//------- display words -------//
365 
366 	const char *msg = ngettext("Acquired Scroll:", "Acquired Scrolls:", scrollCount);
367 
368 	font_san.put( SCROLL_X1+6, SCROLL_Y1+5, msg );
369 
370 	//------- display scrolls ----------//
371 
372 	int x=SCROLL_X1+6, y=SCROLL_Y1+18;
373 
374 	for( i=0 ; i<MAX_RACE ; i++ )
375 	{
376 		if( !nationPtr->know_base_array[i] )
377 			continue;
378 
379 		disp_scroll(x, y, i+1 );
380 
381 		font_san.put( x+36, y+6, _(race_res[i+1]->name) );
382 
383 		x+=105;
384 
385 		if( x+95 > SCROLL_X2 )
386 		{
387 			x  = SCROLL_X1+6;
388 			y += 30;
389 		}
390 	}
391 }
392 //----------- End of static function disp_owned_scroll -----------//
393 
394 
395 //-------- Begin of static function put_heading --------//
396 //
put_heading(char justify,int x1,int y1,int x2,int y2,const char * textPtr)397 static void put_heading(char justify, int x1, int y1, int x2, int y2, const char *textPtr)
398 {
399 	int dispLines=0;
400 	int totalLines=0;
401 	font_san.count_line(x1,y1,x2,y2,textPtr,0,dispLines,totalLines);
402 	if( dispLines > 1 )
403 		font_san.put_paragraph(x1,y1,x2,y2,textPtr,-1,1,1,justify);
404 	else if( y1+7<y2 )
405 		font_san.put_paragraph(x1,y1+7,x2,y2,textPtr,-1,1,1,justify);
406 }
407 //----------- End of static function put_heading -----------//
408