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    : OF_HARB.CPP
22 //Description : Firm Harbor
23 
24 #include <OINFO.h>
25 #include <OVGA.h>
26 #include <vga_util.h>
27 #include <ODATE.h>
28 #include <OHELP.h>
29 #include <OMOUSE.h>
30 #include <OSTR.h>
31 #include <OSYS.h>
32 #include <OFONT.h>
33 #include <OBUTTON.h>
34 #include <OBUTT3D.h>
35 #include <OVBROWIF.h>
36 #include <OTERRAIN.h>
37 #include <OPOWER.h>
38 #include <OREGIONS.h>
39 #include <OU_MARI.h>
40 #include <OGAME.h>
41 #include <ONATION.h>
42 #include <OF_HARB.h>
43 #include <OREMOTE.h>
44 #include <OBUTTCUS.h>
45 #include <OSE.h>
46 #include <OSERES.h>
47 #include "gettext.h"
48 
49 
50 //------------- Define coordinations -----------//
51 
52 enum { SHIP_BROWSE_X1 = INFO_X1,
53 		 SHIP_BROWSE_Y1 = INFO_Y1+54,
54 		 SHIP_BROWSE_X2 = INFO_X2,
55 		 SHIP_BROWSE_Y2 = SHIP_BROWSE_Y1+100
56 	  };
57 
58 enum { SHIP_DET_X1 = INFO_X1,
59 		 SHIP_DET_Y1 = SHIP_BROWSE_Y2+5,
60 		 SHIP_DET_X2 = INFO_X2,
61 		 SHIP_DET_Y2 = SHIP_DET_Y1+92
62 	  };
63 
64 //---------- Define constant ------------//
65 
66 enum { HARBOR_MENU_MAIN,
67 		 HARBOR_MENU_BUILD,
68 	  };
69 
70 // ######## begin Gilbert 22/9 #######//
71 #define BUILD_BUTTON_WIDTH      205
72 #define BUILD_BUTTON_HEIGHT     48
73 #define COUNT_BUTTON_OFFSET_X   160
74 #define COUNT_BUTTON_OFFSET_Y 8
75 // ######## end Gilbert 22/9 #######//
76 #define COUNT_BUTTON_WIDTH		32
77 #define COUNT_BUTTON_HEIGHT	32
78 
79 //----------- Define static variables ----------//
80 
81 static VBrowseIF 		browse_ship;
82 static Button3D		button_build, button_sail;
83 static Button3D		button_cancel_build;
84 static ButtonGroup	button_mode(2);
85 // ###### begin Gilbert 20/9 #######//
86 static short                 button_unit_id[MAX_SHIP_TYPE];
87 static ButtonCustom     button_ship[MAX_SHIP_TYPE];
88 static ButtonCustom     button_queue_ship[MAX_SHIP_TYPE];
89 static int queue_ship_selected = -1;
90 // ###### end Gilbert 20/9 #######//
91 static int				added_count;
92 static ButtonCustom	button_cancel;
93 static int				last_ship_count;
94 static FirmHarbor* 	firm_harbor_ptr;
95 static char       	harbor_menu_mode;
96 static char       	disable_refresh=0;
97 static char				ship_disp_mode=SHIP_MENU_UNIT;
98 
99 //----------- Define static functions ----------//
100 
101 static void put_ship_rec(int recNo, int x, int y, int refreshFlag);
102 static void i_disp_build_button(ButtonCustom *button, int);
103 static void i_disp_queue_button(ButtonCustom *button, int);
104 
105 //--------- Begin of function FirmHarbor::FirmHarbor ---------//
106 //
FirmHarbor()107 FirmHarbor::FirmHarbor()
108 {
109 	ship_count = 0;
110 	build_unit_id = 0;
111 	build_queue_count = 0;
112 
113 	land_region_id = 0;
114 	sea_region_id = 0;
115 	link_checked = 0;
116 	linked_mine_num = linked_factory_num = linked_market_num = 0;
117 	memset(linked_mine_array, 0, sizeof(short)*MAX_LINKED_FIRM_FIRM);
118 	memset(linked_factory_array, 0, sizeof(short)*MAX_LINKED_FIRM_FIRM);
119 	memset(linked_market_array, 0, sizeof(short)*MAX_LINKED_FIRM_FIRM);
120 }
121 //----------- End of function FirmHarbor::FirmHarbor -----------//
122 
123 
124 //--------- Begin of function FirmHarbor::deinit_derived ---------//
125 //
deinit_derived()126 void FirmHarbor::deinit_derived()
127 {
128 	int shipUnitRecno;
129 
130 	for( int i=ship_count ; i>0 ; i-- )
131 	{
132 		shipUnitRecno = ship_recno_array[i-1];
133 
134 		//---- mobilize ships in the harbor ----//
135 
136 		sail_ship( shipUnitRecno, COMMAND_AUTO );
137 
138 		//--- if the ship does not sailed out due to no limit sea space, delete it  ---//
139 
140 		if( ship_count==i )
141 		{
142 			del_hosted_ship(shipUnitRecno);
143 			unit_array.del(shipUnitRecno);
144 		}
145 	}
146 }
147 //----------- End of function FirmHarbor::deinit_derived() -----------//
148 
149 
150 //--------- Begin of function FirmHarbor::init ---------//
151 //
init(int xLoc,int yLoc,int nationRecno,int firmId,const char * buildCode,short builderRecno)152 void FirmHarbor::init(int xLoc, int yLoc, int nationRecno, int firmId, const char* buildCode, short builderRecno)
153 {
154 	// ignore raceId and find north, south, west or east harbor
155 
156 	if( world.get_loc(xLoc+1, yLoc+2)->can_build_harbor(1) )
157 	{
158 		// check north harbour
159 		Firm::init(xLoc, yLoc, nationRecno, firmId, "N", builderRecno);
160 		land_region_id = world.get_loc(xLoc+1, yLoc+2)->region_id;
161 		sea_region_id = world.get_loc(xLoc+1, yLoc)->region_id;
162 	}
163 	else if( world.get_loc(xLoc+1, yLoc)->can_build_harbor(1) )
164 	{
165 		// check south harbour
166 		Firm::init(xLoc, yLoc, nationRecno, firmId, "S", builderRecno);
167 		land_region_id = world.get_loc(xLoc+1, yLoc)->region_id;
168 		sea_region_id = world.get_loc(xLoc+1, yLoc+2)->region_id;
169 	}
170 	else if( world.get_loc(xLoc+2, yLoc+1)->can_build_harbor(1) )
171 	{
172 		// check west harbour
173 		Firm::init(xLoc, yLoc, nationRecno, firmId, "W", builderRecno);
174 		land_region_id = world.get_loc(xLoc+2, yLoc+1)->region_id;
175 		sea_region_id = world.get_loc(xLoc, yLoc+1)->region_id;
176 	}
177 	else if( world.get_loc(xLoc, yLoc+1)->can_build_harbor(1) )
178 	{
179 		// check east harbour
180 		Firm::init(xLoc, yLoc, nationRecno, firmId, "E", builderRecno);
181 		land_region_id = world.get_loc(xLoc, yLoc+1)->region_id;
182 		sea_region_id = world.get_loc(xLoc+2, yLoc+1)->region_id;
183 	}
184 	else
185 	{
186 		err_here();
187 	}
188 
189 	region_id = land_region_id;		// set region_id to land_region_id
190 
191 	//------- update the harbor count of the regions ------//
192 
193 	region_array.update_region_stat();
194 }
195 //----------- End of function FirmHarbor::init -----------//
196 
197 
198 //------- Begin of function FirmHarbor::assign_unit -----------//
199 //
assign_unit(int unitRecno)200 void FirmHarbor::assign_unit(int unitRecno)
201 {
202 	//------- if this is a construction worker -------//
203 
204 	if( unit_array[unitRecno]->skill.skill_id == SKILL_CONSTRUCTION )
205 	{
206 		set_builder(unitRecno);
207 		return;
208 	}
209 
210 	//---------------------------------------//
211 
212 	//if( ship_count==MAX_SHIP_IN_HARBOR )
213 	//	return;
214 	if(ship_count + (build_unit_id>0) == MAX_SHIP_IN_HARBOR)
215 		return; // leave a room for the building unit
216 
217 	add_hosted_ship(unitRecno);
218 
219 	unit_array[unitRecno]->deinit_sprite();
220 
221 	UnitMarine *unitPtr = (UnitMarine*) unit_array[unitRecno];
222 	unitPtr->extra_move_in_beach = NO_EXTRA_MOVE;
223 	unitPtr->deinit_sprite();
224 
225 	//------------------------------------------------//
226 
227 	if( firm_array.selected_recno == firm_recno )
228 		info.disp();
229 }
230 //--------- End of function FirmHarbor::assign_unit -----------//
231 
232 
233 //--------- Begin of function FirmHarbor::next_day ---------//
234 //
next_day()235 void FirmHarbor::next_day()
236 {
237 	//----- call next_day() of the base class -----//
238 
239 	Firm::next_day();
240 
241 	//------- process building -------//
242 
243 	if( build_unit_id )
244 		process_build();
245 	else
246 		process_queue();
247 
248 	//-*********** simulate ship movement ************-//
249 	//if(build_unit_id==0)
250 	//	build_ship(UNIT_CARAVEL, 0);
251 	//-*********** simulate ship movement ************-//
252 }
253 //----------- End of function FirmHarbor::next_day -----------//
254 
255 
256 //--------- Begin of function FirmHarbor::put_info ---------//
257 //
put_info(int refreshFlag)258 void FirmHarbor::put_info(int refreshFlag)
259 {
260 	if( refreshFlag==INFO_REPAINT && !disable_refresh )
261 		harbor_menu_mode = HARBOR_MENU_MAIN;
262 
263 	switch( harbor_menu_mode )
264 	{
265 		case HARBOR_MENU_MAIN:
266 			disp_main_menu(refreshFlag);
267 			break;
268 
269 		case HARBOR_MENU_BUILD:
270 			disp_build_menu(refreshFlag);
271 			break;
272 	}
273 }
274 //----------- End of function FirmHarbor::put_info -----------//
275 
276 
277 //--------- Begin of function FirmHarbor::detect_info ---------//
278 //
detect_info()279 int FirmHarbor::detect_info()
280 {
281 	switch( harbor_menu_mode )
282 	{
283 		case HARBOR_MENU_MAIN:
284 			return detect_main_menu();
285 
286 		case HARBOR_MENU_BUILD:
287 			return detect_build_menu();
288 	}
289 
290 	return 0;
291 }
292 //----------- End of function FirmHarbor::detect_info -----------//
293 
294 
295 //--------- Begin of function FirmHarbor::disp_main_menu ---------//
296 //
disp_main_menu(int refreshFlag)297 void FirmHarbor::disp_main_menu(int refreshFlag)
298 {
299 	firm_harbor_ptr = this;
300 
301 	disp_basic_info(INFO_Y1, refreshFlag);
302 
303 	if( !should_show_harbor_info() )
304 		return;
305 
306 	//-------- display browser -----------//
307 
308 	if( refreshFlag == INFO_REPAINT )
309 	{
310 		browse_ship.init( SHIP_BROWSE_X1, SHIP_BROWSE_Y1, SHIP_BROWSE_X2, SHIP_BROWSE_Y2,
311 								0, 25, ship_count, put_ship_rec );
312 
313 		browse_ship.open(1);
314 
315 		put_det(INFO_REPAINT);
316 	}
317 	else
318 	{
319 		if( last_ship_count != ship_count )
320 		{
321 			last_ship_count = ship_count;
322 			info.disp();
323 		}
324 		else
325 			browse_ship.update();          // update only
326 	}
327 
328 	last_ship_count = ship_count;
329 
330    //-------------------------------//
331 
332 	if( !own_firm() )
333 		return;
334 
335 	//-------- display buttons ---------//
336 
337 	if( refreshFlag == INFO_REPAINT )
338 	{
339 		button_build.paint( SHIP_DET_X1, SHIP_DET_Y2+4, 'A', "MAKESHIP" );
340 		button_sail.paint ( SHIP_DET_X1+BUTTON_ACTION_WIDTH, SHIP_DET_Y2+4, 'A', "SAILOUT" );
341 	}
342 
343 	if( ship_count > 0 )
344 		button_sail.enable();
345 	else
346 		button_sail.disable();
347 
348 	//------ display the info of the ship under construction ------//
349 
350 	disp_build_info(refreshFlag);
351 }
352 //----------- End of function FirmHarbor::disp_main_menu -----------//
353 
354 
355 //--------- Begin of function FirmHarbor::detect_main_menu ---------//
356 //
detect_main_menu()357 int FirmHarbor::detect_main_menu()
358 {
359 	firm_harbor_ptr = this;
360 
361 	if( detect_basic_info() )
362 		return 1;
363 
364 	if( !own_firm() )
365 		return 0;
366 
367 	if( browse_ship.detect() )
368 	{
369 		put_det(INFO_UPDATE);
370 		return 1;
371 	}
372 
373 	if( detect_det() )
374 		return 1;
375 
376 	//------- detect the build button ---------//
377 
378 	if( button_build.detect(GETKEY(KEYEVENT_FIRM_BUILD)) )
379 	{
380 		harbor_menu_mode = HARBOR_MENU_BUILD;
381 		disable_refresh = 1;    // static var for disp_info() only
382 		info.disp();
383 		disable_refresh = 0;
384 		return 1;
385 	}
386 
387 	//-------- detect the sail button ---------//
388 
389 	if( button_sail.detect(GETKEY(KEYEVENT_FIRM_PATROL)) && browse_ship.recno() > 0 )
390 	{
391 		sail_ship( ship_recno_array[browse_ship.recno()-1], COMMAND_PLAYER );
392 		return 1;
393 	}
394 
395 	//---------- detect cancel build button -----------//
396 	if(build_unit_id)
397 	{
398 		if(button_cancel_build.detect())
399 		{
400 			if( !remote.is_enable() )
401 				cancel_build_unit();
402 			else
403 			{
404 				short *shortPtr = (short *)remote.new_send_queue_msg(MSG_F_HARBOR_SKIP_SHIP, sizeof(short));
405 				shortPtr[0] = firm_recno;
406 			}
407 			return 1;
408 		}
409 	}
410 
411 	return 0;
412 }
413 //----------- End of function FirmHarbor::detect_main_menu -----------//
414 
415 
416 //------- Begin of function FirmHarbor::should_show_harbor_info -------//
417 //
should_show_harbor_info()418 int FirmHarbor::should_show_harbor_info()
419 {
420 	if( should_show_info() )
421 		return 1;
422 
423 	//--- if any of the ships in the harbor has the spies of the player ---//
424 
425 	UnitMarine* unitMarine;
426 
427 	for( int i=0 ; i<ship_count ; i++ )
428 	{
429 		unitMarine = (UnitMarine*) unit_array[ ship_recno_array[i] ];
430 
431 		if( unitMarine->should_show_info() )
432 			return 1;
433 	}
434 
435 	return 0;
436 }
437 //------- End of function FirmHarbor::should_show_harbor_info ---------//
438 
439 
440 //--------- Begin of function FirmHarbor::put_det ---------//
441 //
put_det(int refreshFlag)442 void FirmHarbor::put_det(int refreshFlag)
443 {
444 	if( refreshFlag == INFO_REPAINT )
445 		vga_util.d3_panel_up( SHIP_DET_X1, SHIP_DET_Y1, SHIP_DET_X2, SHIP_DET_Y2 );
446 	else
447 		vga_util.blt_buf( SHIP_DET_X1, SHIP_DET_Y1, SHIP_DET_X2, SHIP_DET_Y2, 0 );
448 
449 	if( browse_ship.none_record )
450 		return;
451 
452 	refreshFlag = INFO_REPAINT;		// for calling disp_ship_units() and disp_ship_goods()
453 
454 	//------- display info of the ship --------//
455 
456 	UnitMarine* shipUnitPtr  = (UnitMarine*) unit_array[ ship_recno_array[browse_ship.recno()-1] ];
457 	UnitInfo*   shipUnitInfo = unit_res[shipUnitPtr->unit_id];
458 
459 	//----- if the ship can carry both goods and units, display mode selection button ---//
460 
461 	if( shipUnitInfo->carry_goods_capacity > 0 &&
462 		 shipUnitInfo->carry_unit_capacity > 0 )
463 	{
464 		button_mode[0].create_text( SHIP_DET_X1+10, SHIP_DET_Y1+3, SHIP_DET_X1+80, SHIP_DET_Y1+19, _("Units") );
465 		button_mode[1].create_text( SHIP_DET_X1+90, SHIP_DET_Y1+3, SHIP_DET_X2-10, SHIP_DET_Y1+19, _("Goods") );
466 		button_mode.paint(ship_disp_mode);
467 
468 		if( ship_disp_mode == SHIP_MENU_UNIT )
469 			disp_ship_units(shipUnitPtr, SHIP_DET_Y1+22, refreshFlag);
470 		else
471 			disp_ship_goods(shipUnitPtr, SHIP_DET_Y1+22, refreshFlag);
472 	}
473 	else if( shipUnitInfo->carry_goods_capacity > 0 )
474 	{
475 		disp_ship_goods(shipUnitPtr, SHIP_DET_Y1+22, refreshFlag);
476 	}
477 	else if( shipUnitInfo->carry_unit_capacity > 0 )
478 	{
479 		disp_ship_units(shipUnitPtr, SHIP_DET_Y1+22, refreshFlag);
480 	}
481 }
482 //----------- End of function FirmHarbor::put_det -----------//
483 
484 
485 //--------- Begin of function FirmHarbor::detect_det ---------//
486 //
detect_det()487 int FirmHarbor::detect_det()
488 {
489 	if( browse_ship.none_record )
490 		return 0;
491 
492 	UnitMarine* shipUnitPtr  = (UnitMarine*) unit_array[ ship_recno_array[browse_ship.recno()-1] ];
493 	UnitInfo*   shipUnitInfo = unit_res[shipUnitPtr->unit_id];
494 
495 	if( shipUnitInfo->carry_goods_capacity > 0 &&
496 		 shipUnitInfo->carry_unit_capacity > 0 )
497 	{
498 		if( button_mode.detect() >= 0 )
499 		{
500 			ship_disp_mode = button_mode.button_pressed;
501 			vga_util.blt_buf( SHIP_DET_X1, SHIP_DET_Y1+22, SHIP_DET_X2, SHIP_DET_Y2, 0 );
502 			put_det(INFO_UPDATE);
503 			return 1;
504 		}
505 	}
506 
507 	return 0;
508 }
509 //----------- End of function FirmHarbor::detect_det -----------//
510 
511 
512 //--------- Begin of function FirmHarbor::disp_ship_goods ---------//
513 //
514 // Display goods carried by the selected ship.
515 //
disp_ship_goods(UnitMarine * shipUnit,int dispY1,int refreshFlag)516 void FirmHarbor::disp_ship_goods(UnitMarine* shipUnit, int dispY1, int refreshFlag)
517 {
518 	int	x=INFO_X1+20, y=dispY1+5;
519 	String str;
520 
521 	int i;
522 	for(i=0; i<MAX_RAW; i++, x+=60)
523 	{
524 		vga_front.d3_panel_up( x, y, x+RAW_SMALL_ICON_WIDTH+5, y+RAW_SMALL_ICON_HEIGHT+5 );
525 
526 		raw_res.put_small_raw_icon( x+3, y+3, i+1 );
527 
528 		font_san.disp( x+25, y+2, shipUnit->raw_qty_array[i], 1, x+59 );
529 	}
530 
531 	x =INFO_X1+20;
532 	y+=19;
533 
534 	for( i=0; i<MAX_PRODUCT; i++, x+=60)
535 	{
536 		vga_front.d3_panel_up( x, y, x+RAW_SMALL_ICON_WIDTH+5, y+RAW_SMALL_ICON_HEIGHT+5 );
537 
538 		raw_res.put_small_product_icon( x+3, y+3, i+1 );
539 
540 		font_san.disp( x+25, y+2, shipUnit->product_raw_qty_array[i], 1, x+59 );
541 	}
542 }
543 //---------- End of function FirmHarbor::disp_ship_goods ----------//
544 
545 
546 //--------- Begin of function FirmHarbor::disp_ship_units ---------//
547 //
disp_ship_units(UnitMarine * shipUnit,int dispY1,int refreshFlag)548 void FirmHarbor::disp_ship_units(UnitMarine* shipUnit, int dispY1, int refreshFlag)
549 {
550 	//------ display population composition -------//
551 
552 	int	  x, y;
553 	Unit*   unitPtr;
554 	static  short last_unit_race_array[MAX_UNIT_IN_SHIP];
555 
556 	dispY1+=5;
557 
558 	for( int i=0 ; i<MAX_UNIT_IN_SHIP ; i++ )
559 	{
560 		x = INFO_X1+10+i%5*37;
561 		y = dispY1+i/5*29;
562 
563 		if( i<shipUnit->unit_count )
564 		{
565 			unitPtr = unit_array[ shipUnit->unit_recno_array[i] ];
566 
567 			if( refreshFlag==INFO_REPAINT || last_unit_race_array[i] != unitPtr->race_id )
568 			{
569 				vga_front.d3_panel_up( x, y, x+27, y+23, 1 );
570 				// ####### begin Gilbert 17/10 ##########//
571 				vga_front.put_bitmap(x+2, y+2, unit_res[unitPtr->unit_id]->get_small_icon_ptr(unitPtr->rank_id));
572 				// ####### end Gilbert 17/10 ##########//
573 			}
574 
575 			//------- set help parameters ---------//
576 
577 			if( mouse.in_area(x, y, x+27, y+23) )
578 				help.set_unit_help( unitPtr->unit_id, 0, x, y, x+27, y+23 );
579 
580 			//------------------------------------//
581 
582 			last_unit_race_array[i] = unitPtr->race_id;
583 		}
584 		else
585 		{
586 			if( last_unit_race_array[i] != 0 )
587 			{
588 				vga_util.blt_buf( x-2, y-2, x+36, y+25, 0 );
589 				last_unit_race_array[i] = 0;
590 			}
591 		}
592 	}
593 }
594 //----------- End of function FirmHarbor::disp_ship_units -----------//
595 
596 
597 //--------- Begin of function FirmHarbor::disp_build_menu ---------//
598 //
disp_build_menu(int refreshFlag)599 void FirmHarbor::disp_build_menu(int refreshFlag)
600 {
601 	// ###### begin Gilbert 20/9 ######//
602 	if( refreshFlag == INFO_UPDATE )
603 	{
604 		for( int b=0; b<added_count; ++b )
605 		{
606 			button_ship[b].paint(-1, 0);
607 			// button_queue_ship[b] is called by button_ship[b].paint();
608 		}
609 	}
610 	else if( refreshFlag == INFO_REPAINT )
611 	{
612 		added_count=0;
613 		int 	 unitId, x=INFO_X1, y=INFO_Y1;
614 		for( unitId=1; unitId<=MAX_UNIT_TYPE ; unitId++ )
615 		{
616 			if( unit_res[unitId]->unit_class == UNIT_CLASS_SHIP )
617 			{
618 				if( unit_res[unitId]->get_nation_tech_level(nation_recno) > 0 )
619 				{
620 					// disp_build_button( y, unitId, 1);
621 					button_queue_ship[added_count].create(x+COUNT_BUTTON_OFFSET_X, y+COUNT_BUTTON_OFFSET_Y,
622 						x+COUNT_BUTTON_OFFSET_X+COUNT_BUTTON_WIDTH-1, y+COUNT_BUTTON_OFFSET_Y+COUNT_BUTTON_HEIGHT-1,
623 						i_disp_queue_button, ButtonCustomPara(this, unitId) );
624 					button_ship[added_count].paint(x, y, x+BUILD_BUTTON_WIDTH-1, y+BUILD_BUTTON_HEIGHT-1,
625 						i_disp_build_button, ButtonCustomPara(&button_queue_ship[added_count], unitId) );
626 
627 					err_when(added_count >= MAX_SHIP_TYPE);
628 					button_unit_id[added_count++] = unitId;
629 					y += BUILD_BUTTON_HEIGHT;
630 				}
631 			}
632 		}
633 
634 		if( !added_count || queue_ship_selected >= added_count)
635 			queue_ship_selected = -1;
636 
637 		button_cancel.paint(x, y, x+BUILD_BUTTON_WIDTH-1, y+BUILD_BUTTON_HEIGHT*3/4,
638 			ButtonCustom::disp_text_button_func, ButtonCustomPara((void*)_("Done"),0) );
639 	}
640 	// ###### end Gilbert 20/9 ######//
641 }
642 //----------- End of function FirmHarbor::disp_build_menu -----------//
643 
644 
645 // ####### begin Gilbert 20/9 ########//
646 /*
647 //--------- Begin of function FirmHarbor::disp_build_button ---------//
648 void FirmHarbor::disp_build_button(int y, int unitId, int buttonUp)
649 {
650 	int x;
651 	int y0 = y;
652 	if(buttonUp)
653 	{
654 		vga_util.d3_panel_up(INFO_X1, y, INFO_X2-1, y+BUILD_BUTTON_HEIGHT-2);
655 		x = INFO_X1;
656 	}
657 	else
658 	{
659 		vga_util.d3_panel_down(INFO_X1, y, INFO_X2-1, y+BUILD_BUTTON_HEIGHT-2);
660 		x = INFO_X1+1;
661 		y++;
662 	}
663 
664 	// display unit large icon
665 	UnitInfo* unitInfo = unit_res[unitId];
666 	vga_front.put_bitmap(x+6, y+4, unitInfo->get_large_icon_ptr(0));
667 
668 	//-------- display unit name --------//
669 
670 	String str;
671 	str = _(unitInfo->name);
672 	font_bible.put( x+60, y+14, str );
673 	disp_queue_button(y0+COUNT_BUTTON_OFFSET_Y, unitId, 1);
674 }
675 //----------- End of function FirmHarbor::disp_build_button -----------//
676 */
677 
678 
679 //-------- Begin of function i_disp_build_button --------//
680 //
i_disp_build_button(ButtonCustom * button,int repaintBody)681 static void i_disp_build_button(ButtonCustom *button, int repaintBody)
682 {
683 	int x1 = button->x1;
684 	int y1 = button->y1;
685 	int x2 = button->x2;
686 	int y2 = button->y2;
687 	if( !button->pushed_flag )
688 	{
689 		if( repaintBody )
690 		{
691 			vga_util.blt_buf(x1, y1, x2, y2, 0);
692 			vga_util.d3_panel2_up( x1, y1, x2, y2, 1 );
693 		}
694 		x2--;
695 		y2--;
696 	}
697 	else
698 	{
699 		if( repaintBody )
700 		{
701 			vga_util.blt_buf(x1, y1, x2, y2, 0);
702 			vga_util.d3_panel2_down( x1, y1, x2, y2, 1 );
703 		}
704 		x1++;
705 		y1++;
706 	}
707 
708 	ButtonCustom *queueButton = (ButtonCustom *)button->custom_para.ptr;
709 	if( repaintBody)
710 	{
711 		// display unit large icon
712 		short unitId = button->custom_para.value;
713 		UnitInfo* unitInfo = unit_res[unitId];
714 		vga_front.put_bitmap(x1+6, y1+4, unitInfo->get_large_icon_ptr(0));
715 
716 		err_when( button->custom_para.value != queueButton->custom_para.value);
717 
718 		//-------- display unit name --------//
719 
720 		String str;
721 
722 		str = "";
723 
724 		if( queue_ship_selected>=0 && button_unit_id[queue_ship_selected] == unitId )
725 			str += ">";
726 
727 		str += _(unitInfo->name);
728 
729 		if( unitInfo->unit_class == UNIT_CLASS_WEAPON )		// add version no.
730 		{
731 			FirmHarbor *harbor = (FirmHarbor *)queueButton->custom_para.ptr;
732 			int techLevel = unitInfo->get_nation_tech_level(harbor->nation_recno);
733 
734 			if( techLevel > 1 )
735 			{
736 				str += " ";
737 				str += misc.roman_number(techLevel);
738 			}
739 		}
740 
741 		if( queue_ship_selected >=0 && button_unit_id[queue_ship_selected] == unitId )
742 			str += "<";
743 
744 		font_bible.put( x1+60, y1+13, str );
745 	}
746 
747 	// display small button
748 	queueButton->paint(-1, repaintBody);
749 }
750 //--------- End of static function i_disp_build_button ---------//
751 
752 
753 /*
754 //--------- Begin of function FirmHarbor::disp_queue_button ---------//
755 void FirmHarbor::disp_queue_button(int y, int unitId, int buttonUp)
756 {
757 	//----- count the no. of units queued for this ship ------//
758 	int x=INFO_X1+2+COUNT_BUTTON_OFFSET_X;
759 	int queuedCount=0;
760 
761 	for(int i=0; i<build_queue_count; i++)
762 	{
763 		if(build_queue_array[i] == unitId)
764 			queuedCount++;
765 	}
766 
767 	if(build_unit_id==unitId)
768 		queuedCount++;
769 
770 	if(buttonUp)
771 		vga_util.d3_panel_up(x, y, x+COUNT_BUTTON_WIDTH-1, y+COUNT_BUTTON_HEIGHT-1);
772 	else
773 	{
774 		vga_util.d3_panel_down(x, y, x+COUNT_BUTTON_WIDTH-1, y+COUNT_BUTTON_HEIGHT-1);
775 		x++;
776 		y++;
777 	}
778 
779 	font_san.center_put(x, y, x+COUNT_BUTTON_WIDTH-1 , y+COUNT_BUTTON_HEIGHT-1, misc.format(queuedCount));
780 }
781 //----------- End of function FirmHarbor::disp_queue_button -----------//
782 */
783 
784 
785 //-------- Begin of static function i_disp_queue_button --------//
786 //
i_disp_queue_button(ButtonCustom * button,int repaintBody)787 static void i_disp_queue_button(ButtonCustom *button, int repaintBody)
788 {
789 	FirmHarbor *harbor= (FirmHarbor *)button->custom_para.ptr;
790 
791 	int x1 = button->x1;
792 	int y1 = button->y1;
793 	int x2 = button->x2;
794 	int y2 = button->y2;
795 	if( !button->pushed_flag )
796 	{
797 		if( repaintBody )
798 		{
799 			vga_util.blt_buf(x1, y1, x2, y2, 0);
800 			vga_util.d3_panel2_up( x1, y1, x2, y2, 1, 1);
801 		}
802 		x2--;
803 		y2--;
804 	}
805 	else
806 	{
807 		if( repaintBody )
808 		{
809 			vga_util.blt_buf(x1, y1, x2, y2, 0);
810 			vga_util.d3_panel2_down( x1, y1, x2, y2, 1, 1);
811 		}
812 		x1++;
813 		y1++;
814 	}
815 
816 	//----- count the no. of units queued for this weapon ------//
817 
818 	short unitId = button->custom_para.value;
819 	int queuedCount=0;
820 	for( int i=0 ; i<harbor->build_queue_count ; i++ )
821 	{
822 		if( harbor->build_queue_array[i] == unitId )
823 			queuedCount++;
824 	}
825 	if( harbor->build_unit_id == unitId)
826 		queuedCount++;
827 
828 	font_mid.center_put( x1+3, y1+3, x2-3, y2-3, misc.format(queuedCount), 1);
829 }
830 //--------- End of static function i_disp_queue_button ---------//
831 // ####### end Gilbert 20/9 #######//
832 
833 
834 //--------- Begin of function FirmHarbor::detect_build_menu ---------//
835 //
detect_build_menu()836 int FirmHarbor::detect_build_menu()
837 {
838 	int 	 	 unitId, x=INFO_X1+2, y=INFO_Y1, rc, quitFlag, waitFlag;
839 	UnitInfo* unitInfo;
840 
841 	waitFlag = 0;
842 	for(int b=0; b<added_count; ++b)
843 	{
844 		// ###### begin Gilbert 20/9 #########//
845 		unitId = button_ship[b].custom_para.value;
846 		// ###### end Gilbert 20/9 #########//
847 		unitInfo = unit_res[unitId];
848 
849 		//------ detect pressing on the small queue count button -------//
850 
851 		// ####### begin Gilbert 20/9 ########//
852 		rc = 0;
853 		if( (rc = button_queue_ship[b].detect(0,0,2)) != 0 )		// both button
854 		{
855 			quitFlag = 0;		// don't quit the menu right after pressing the button
856 		}
857 
858 		//------ detect pressing on the big button -------//
859 		else if( !button_queue_ship[b].button_wait && ((rc = button_ship[b].detect(0,0,2)) != 0) )
860 		{
861 			quitFlag = 1;		// quit the menu right after pressing the button
862 		}
863 		// ####### end Gilbert 20/9 ########//
864 
865 		if( button_queue_ship[b].button_wait || button_ship[b].button_wait )
866 			waitFlag = 1;
867 
868 		int shiftPressed = mouse.event_skey_state & SHIFT_KEY_MASK;
869 
870 		//------- process the action --------//
871 
872 		if( rc > 0 )
873 		{
874 			// Holding shift will use batches of FIRMWAR_BUILD_BATCH_COUNT
875 			int createRemoveAmount = shiftPressed ? HARBOR_BUILD_BATCH_COUNT : 1;
876 
877 			if( rc==1 )		// left button
878 			{
879 				if( remote.is_enable() )
880 				{
881 					// packet structure : <firm recno> <unit Id> <amount>
882 					short *shortPtr = (short *)remote.new_send_queue_msg(MSG_F_HARBOR_BUILD_SHIP, 3*sizeof(short) );
883 					shortPtr[0] = firm_recno;
884 					shortPtr[1] = unitId;
885 					shortPtr[2] = createRemoveAmount;
886 				}
887 				else
888 					add_queue(unitId, createRemoveAmount);
889 				// ##### begin Gilbert 25/9 ######//
890 				se_ctrl.immediate_sound("TURN_ON");
891 				// ##### end Gilbert 25/9 ######//
892 			}
893 			else 				// right button - remove queue
894 			{
895 				if( remote.is_enable() )
896 				{
897 					// packet structure : <firm recno> <unit Id> <amount>
898 					short *shortPtr = (short *)remote.new_send_queue_msg(MSG_F_HARBOR_BUILD_SHIP, 3*sizeof(short) );
899 					shortPtr[0] = firm_recno;
900 					shortPtr[1] = -unitId;
901 					shortPtr[2] = createRemoveAmount;
902 				}
903 				else
904 					remove_queue(unitId, createRemoveAmount);
905 
906 				// ##### begin Gilbert 25/9 ######//
907 				se_ctrl.immediate_sound("TURN_OFF");
908 				// ##### end Gilbert 25/9 ######//
909 			}
910 
911 			if( quitFlag )
912 				info.disp();		// info.disp() will call put_info() which will switch mode back to the main menu mode
913 			else
914 			// ######## begin Gilbert 20/9 ########//
915 				// disp_queue_button(y+COUNT_BUTTON_OFFSET_Y, unitId, 1);
916 				info.update();
917 			// ######## end Gilbert 20/9 ########//
918 
919 			return 1;
920 		}
921 
922 		y += BUILD_BUTTON_HEIGHT;
923 	}
924 
925 	//------ detect the cancel button --------//
926 
927 	if( button_cancel.detect() || (!waitFlag && mouse.any_click(1)) )		// press the cancel button or right click
928 	{
929 		harbor_menu_mode = HARBOR_MENU_MAIN;
930 		info.disp();
931 		// ###### begin Gilbert 26/9 #######//
932 		se_ctrl.immediate_sound("TURN_OFF");
933 		// ###### end Gilbert 26/9 #######//
934 		return 1;
935 	}
936 
937 	//------ detect production selecting hotkeys --------//
938 
939 	if( added_count>0 && ISKEY(KEYEVENT_MANUF_QUEUE_UP) )
940 	{
941 		queue_ship_selected--;
942 		if( queue_ship_selected < 0 )
943 			queue_ship_selected = added_count-1;
944 		disp_build_menu(INFO_REPAINT);
945 		return 1;
946 	}
947 
948 	if( added_count>0 && ISKEY(KEYEVENT_MANUF_QUEUE_DOWN) )
949 	{
950 		queue_ship_selected++;
951 		if( queue_ship_selected >= added_count )
952 			queue_ship_selected = 0;
953 		disp_build_menu(INFO_REPAINT);
954 		return 1;
955 	}
956 
957 	if( queue_ship_selected>=0 && ISKEY(KEYEVENT_MANUF_QUEUE_ADD) )
958 	{
959 		if( remote.is_enable() )
960 		{
961 			// packet structure : <firm recno> <unit Id>
962 			short *shortPtr = (short *)remote.new_send_queue_msg(MSG_F_HARBOR_BUILD_SHIP, 3*sizeof(short) );
963 			shortPtr[0] = firm_recno;
964 			shortPtr[1] = button_unit_id[queue_ship_selected];
965 			shortPtr[2] = 1;
966 		}
967 		else
968 			add_queue(button_unit_id[queue_ship_selected], 1);
969 
970 		se_ctrl.immediate_sound("TURN_ON");
971 		info.update();
972 		return 1;
973 	}
974 
975 	if( queue_ship_selected>=0 && ISKEY(KEYEVENT_MANUF_QUEUE_ADD_BATCH) )
976 	{
977 		if( remote.is_enable() )
978 		{
979 			// packet structure : <firm recno> <unit Id>
980 			short *shortPtr = (short *)remote.new_send_queue_msg(MSG_F_HARBOR_BUILD_SHIP, 3*sizeof(short) );
981 			shortPtr[0] = firm_recno;
982 			shortPtr[1] = button_unit_id[queue_ship_selected];
983 			shortPtr[2] = HARBOR_BUILD_BATCH_COUNT;
984 		}
985 		else
986 			add_queue(button_unit_id[queue_ship_selected], HARBOR_BUILD_BATCH_COUNT);
987 
988 		se_ctrl.immediate_sound("TURN_ON");
989 		info.update();
990 		return 1;
991 	}
992 
993 	if( queue_ship_selected>=0 && ISKEY(KEYEVENT_MANUF_QUEUE_REMOVE) )
994 	{
995 		if( remote.is_enable() )
996 		{
997 			// packet structure : <firm recno> <unit Id>
998 			short *shortPtr = (short *)remote.new_send_queue_msg(MSG_F_HARBOR_BUILD_SHIP, 3*sizeof(short) );
999 			shortPtr[0] = firm_recno;
1000 			shortPtr[1] = -button_unit_id[queue_ship_selected];
1001 			shortPtr[2] = 1;
1002 		}
1003 		else
1004 			remove_queue(button_unit_id[queue_ship_selected], 1);
1005 
1006 		se_ctrl.immediate_sound("TURN_OFF");
1007 		info.update();
1008 		return 1;
1009 	}
1010 
1011 	if( queue_ship_selected>=0 && ISKEY(KEYEVENT_MANUF_QUEUE_REMOVE_BATCH) )
1012 	{
1013 		if( remote.is_enable() )
1014 		{
1015 			// packet structure : <firm recno> <unit Id>
1016 			short *shortPtr = (short *)remote.new_send_queue_msg(MSG_F_HARBOR_BUILD_SHIP, 3*sizeof(short) );
1017 			shortPtr[0] = firm_recno;
1018 			shortPtr[1] = -button_unit_id[queue_ship_selected];
1019 			shortPtr[2] = HARBOR_BUILD_BATCH_COUNT;
1020 		}
1021 		else
1022 			remove_queue(button_unit_id[queue_ship_selected], HARBOR_BUILD_BATCH_COUNT);
1023 
1024 		se_ctrl.immediate_sound("TURN_OFF");
1025 		info.update();
1026 		return 1;
1027 	}
1028 
1029 	return 0;
1030 }
1031 //----------- End of function FirmHarbor::detect_build_menu -----------//
1032 
1033 
1034 //--------- Begin of function FirmHarbor::build_ship ---------//
1035 //
1036 
build_ship(int unitId,char)1037 void FirmHarbor::build_ship(int unitId, char)
1038 {
1039 	if(ship_count>=MAX_SHIP_IN_HARBOR)
1040 		return;
1041 
1042 	Nation* nationPtr = nation_array[nation_recno];
1043 
1044 	if( nationPtr->cash < unit_res[unitId]->build_cost )
1045 		return;
1046 
1047 	nationPtr->add_expense( EXPENSE_SHIP, unit_res[unitId]->build_cost);
1048 
1049 	build_unit_id  = unitId;
1050 	start_build_frame_no = sys.frame_count;
1051 }
1052 
1053 //----------- End of function FirmHarbor::build_ship -----------//
1054 
1055 
1056 //--------- Begin of function FirmHarbor::sail_ship ---------//
1057 //
sail_ship(int unitRecno,char remoteAction)1058 void FirmHarbor::sail_ship(int unitRecno, char remoteAction)
1059 {
1060 	if( !remoteAction && remote.is_enable() )
1061 	{
1062 		// packet structure : <firm recno> <browseRecno>
1063 		short *shortPtr = (short *)remote.new_send_queue_msg(MSG_F_HARBOR_SAIL_SHIP, 2*sizeof(short) );
1064 		shortPtr[0] = firm_recno;
1065 		shortPtr[1] = unitRecno;
1066 		return;
1067 	}
1068 
1069 	//----- get the browse recno of the ship in the harbor's ship_recno_array[] ----//
1070 
1071 	int browseRecno=0;
1072 
1073 	for( int i=0 ; i<ship_count ; i++ )
1074 	{
1075 		if( ship_recno_array[i] == unitRecno )
1076 		{
1077 			browseRecno = i+1;
1078 			break;
1079 		}
1080 	}
1081 
1082 	err_when( !browseRecno );
1083 	// ###### begin Gilbert 10/11 ########//
1084 	if( !browseRecno )
1085 		return;
1086 	// ###### end Gilbert 10/11 ########//
1087 
1088 	//------------------------------------------------------------//
1089 
1090 	Unit* unitPtr = unit_array[unitRecno];
1091 
1092 	err_when( unitPtr->unit_mode != UNIT_MODE_IN_HARBOR || unitPtr->unit_mode_para != firm_recno );
1093 
1094 	SpriteInfo*	spriteInfo = unitPtr->sprite_info;
1095 	int 			xLoc=loc_x1; // xLoc & yLoc are used for returning results
1096 	int 			yLoc=loc_y1;
1097 
1098 	if(!world.locate_space(&xLoc, &yLoc, loc_x2, loc_y2, spriteInfo->loc_width, spriteInfo->loc_height, UNIT_SEA, sea_region_id))
1099 		return;
1100 
1101 	unitPtr->init_sprite(xLoc, yLoc);
1102 
1103 	del_hosted_ship(ship_recno_array[browseRecno-1]);
1104 
1105 	//-------- selected the ship --------//
1106 
1107 	if( firm_array.selected_recno == firm_recno &&
1108 		 nation_recno == nation_array.player_recno )
1109 	{
1110 		power.reset_selection();
1111 		unitPtr->selected_flag = 1;
1112 		unit_array.selected_recno = unitPtr->sprite_recno;
1113 		unit_array.selected_count = 1;
1114 
1115 		info.disp();
1116 	}
1117 }
1118 //----------- End of function FirmHarbor::sail_ship -----------//
1119 
1120 
1121 //--------- Begin of function FirmHarbor::disp_build_info ---------//
1122 //
disp_build_info(int refreshFlag)1123 void FirmHarbor::disp_build_info(int refreshFlag)
1124 {
1125 	if( !build_unit_id || nation_recno!=nation_array.player_recno )
1126 		return;
1127 
1128 	int dispY1 = INFO_Y1+26;
1129 	int x=MSG_X1+3, y=MSG_Y1+3;
1130 
1131 	if( refreshFlag == INFO_REPAINT )
1132 	{
1133 		vga_util.d3_panel_up( MSG_X1, MSG_Y1, MSG_X2, MSG_Y2 );
1134 
1135 		vga_util.d3_panel_down(x, y, x+UNIT_SMALL_ICON_WIDTH+3, y+UNIT_SMALL_ICON_HEIGHT+3 );
1136 		vga_front.put_bitmap(x+2, y+2, unit_res[build_unit_id]->get_small_icon_ptr(RANK_SOLDIER) );
1137 	}
1138 
1139 	vga_front.indicator( 0, x+UNIT_SMALL_ICON_WIDTH+6, y,
1140 		(float)(sys.frame_count-start_build_frame_no),
1141 		(float)unit_res[build_unit_id]->build_days * FRAMES_PER_DAY, VGA_GRAY );
1142 
1143 	button_cancel_build.paint(MSG_X2-27, MSG_Y1+2, "V_X-U", "V_X-D");
1144 	button_cancel_build.set_help_code( "CANCELSHP" );
1145 }
1146 //----------- End of function FirmHarbor::disp_build_info -----------//
1147 
1148 
1149 //--------- Begin of function FirmHarbor::process_build ---------//
1150 //
process_build()1151 void FirmHarbor::process_build()
1152 {
1153 	int totalBuildDays = unit_res[build_unit_id]->build_days;
1154 
1155 	err_when( !build_unit_id );
1156 
1157 	if( (int)(sys.frame_count-start_build_frame_no) / FRAMES_PER_DAY >= totalBuildDays )
1158 	{
1159 		int unitRecno = unit_array.add_unit( build_unit_id, nation_recno );
1160 
1161 		add_hosted_ship(unitRecno);
1162 
1163 		if( own_firm() )
1164 			se_res.far_sound(center_x, center_y, 1, 'F', firm_id, "FINS", 'S', unit_res[build_unit_id]->sprite_id);
1165 
1166 		build_unit_id = 0;
1167 
1168 		// ##### begin Gilbert 20/9 ########//
1169 		if( firm_array.selected_recno == firm_recno )
1170 		{
1171 			disable_refresh = 1;
1172 			info.disp();
1173 			disable_refresh = 0;
1174 		}
1175 		// ##### end Gilbert 20/9 ########//
1176 
1177 		//-*********** simulate ship movement ************-//
1178 		//sail_ship(ship_recno_array[0], 0);
1179 		//-*********** simulate ship movement ************-//
1180 	}
1181 }
1182 //----------- End of function FirmHarbor::process_build -----------//
1183 
1184 
1185 //--------- Begin of function FirmHarbor::cancel_build_unit ---------//
cancel_build_unit()1186 void FirmHarbor::cancel_build_unit()
1187 {
1188 	build_unit_id = 0;
1189 
1190 	if( firm_array.selected_recno == firm_recno )
1191 	{
1192 		disable_refresh = 1;
1193 		info.disp();
1194 		disable_refresh = 0;
1195 	}
1196 }
1197 //----------- End of function FirmHarbor::cancel_build_unit -----------//
1198 
1199 
1200 //--------- Begin of function FirmHarbor::add_hosted_ship ---------//
1201 //
add_hosted_ship(int shipRecno)1202 void FirmHarbor::add_hosted_ship(int shipRecno)
1203 {
1204 	err_when( ship_count == MAX_SHIP_IN_HARBOR );
1205 
1206 	ship_recno_array[ship_count++] = shipRecno;
1207 
1208 	//---- set the unit_mode of the ship ----//
1209 
1210 	err_when( firm_id != FIRM_HARBOR );
1211 
1212 	unit_array[shipRecno]->set_mode(UNIT_MODE_IN_HARBOR, firm_recno);
1213 
1214 	//---------------------------------------//
1215 
1216 	if( firm_recno == firm_array.selected_recno )
1217 		put_info(INFO_UPDATE);
1218 }
1219 //----------- End of function FirmHarbor::add_hosted_ship -----------//
1220 
1221 
1222 //--------- Begin of function FirmHarbor::del_hosted_ship ---------//
1223 //
del_hosted_ship(int delUnitRecno)1224 void FirmHarbor::del_hosted_ship(int delUnitRecno)
1225 {
1226 	//---- reset the unit_mode of the ship ----//
1227 
1228 	unit_array[delUnitRecno]->set_mode(0);
1229 
1230 	//-----------------------------------------//
1231 
1232 	int i;
1233 	for( i=0 ; i<ship_count ; i++ )
1234 	{
1235 		if( ship_recno_array[i] == delUnitRecno )
1236 		{
1237 			err_when( ship_count > MAX_SHIP_IN_HARBOR );
1238 
1239 			misc.del_array_rec( ship_recno_array, ship_count, sizeof(ship_recno_array[0]), i+1 );
1240 			break;
1241 		}
1242 	}
1243 
1244 	err_when( i==ship_count );
1245 
1246 	ship_count--;
1247 
1248 	if( firm_recno == firm_array.selected_recno )
1249 		put_info(INFO_UPDATE);
1250 }
1251 //----------- End of function FirmHarbor::del_hosted_ship -----------//
1252 
1253 
1254 //--------- Begin of function FirmHarbor::update_linked_firm_info ---------//
1255 // Note: when ai is finished, ai_link_checked may be used as am indicator
1256 //			for link_checked.  Performance should be improved in this way.
1257 //
update_linked_firm_info()1258 void FirmHarbor::update_linked_firm_info()
1259 {
1260 	if(link_checked)
1261 		return; // no need to check again
1262 
1263 	linked_mine_num = linked_factory_num = linked_market_num = 0;
1264 	memset(linked_mine_array, 0, sizeof(short)*MAX_LINKED_FIRM_FIRM);
1265 	memset(linked_factory_array, 0, sizeof(short)*MAX_LINKED_FIRM_FIRM);
1266 	memset(linked_market_array, 0, sizeof(short)*MAX_LINKED_FIRM_FIRM);
1267 
1268 	Firm *firmPtr;
1269 	Nation *nationPtr;
1270 	for(int i=linked_firm_count-1; i>=0; i--)
1271 	{
1272 		if(linked_firm_enable_array[i]!=LINK_EE)
1273 			continue;
1274 
1275 		firmPtr = firm_array[linked_firm_array[i]];
1276 		if(!nation_array[nation_recno]->get_relation(firmPtr->nation_recno)->trade_treaty)
1277 			continue;
1278 
1279 		switch(firmPtr->firm_id)
1280 		{
1281 			case FIRM_MINE:
1282 					nationPtr = nation_array[firmPtr->nation_recno];
1283 					//if(nationPtr->get_relation_status(nation_recno)<=NATION_TENSE)
1284 					//	continue;
1285 
1286 					linked_mine_array[linked_mine_num] = firmPtr->firm_recno;
1287 					linked_mine_num++;
1288 					break;
1289 
1290 			case FIRM_FACTORY:
1291 					nationPtr = nation_array[firmPtr->nation_recno];
1292 					//if(nationPtr->get_relation_status(nation_recno)<=NATION_TENSE)
1293 					//	continue;
1294 
1295 					linked_factory_array[linked_factory_num] = firmPtr->firm_recno;
1296 					linked_factory_num++;
1297 					break;
1298 
1299 			case FIRM_MARKET:
1300 					nationPtr = nation_array[firmPtr->nation_recno];
1301 					//if(nationPtr->get_relation_status(nation_recno)<=NATION_TENSE)
1302 					//	continue;
1303 
1304 					linked_market_array[linked_market_num] = firmPtr->firm_recno;
1305 					linked_market_num++;
1306 					break;
1307 		}
1308 	}
1309 }
1310 //----------- End of function FirmHarbor::update_linked_firm_info -----------//
1311 
1312 
1313 //--------- Begin of function FirmHarbor::process_queue ---------//
process_queue()1314 void FirmHarbor::process_queue()
1315 {
1316 	if(build_queue_count>0)
1317 	{
1318 		build_ship(build_queue_array[0], COMMAND_AUTO);
1319 
1320 		// remove the queue no matter build_ship success or not
1321 
1322 		misc.del_array_rec( build_queue_array, build_queue_count, sizeof(build_queue_array[0]), 1 );
1323 		build_queue_count--;
1324 
1325 		if( firm_array.selected_recno == firm_recno )
1326 		{
1327 			disable_refresh = 1;
1328 			info.disp();
1329 			disable_refresh = 0;
1330 		}
1331 	}
1332 }
1333 //----------- End of function FirmHarbor::process_queue -----------//
1334 
1335 
1336 //--------- Begin of function FirmHarbor::add_queue ---------//
add_queue(int unitId,int amount)1337 void FirmHarbor::add_queue(int unitId, int amount)
1338 {
1339 	err_when(amount < 0);
1340 	if (amount < 0) return;
1341 
1342 	int queueSpace = MAX_BUILD_SHIP_QUEUE - build_queue_count  - (build_unit_id>0);
1343 	int enqueueAmount = MIN(queueSpace, amount);
1344 
1345 	for (int i = 0; i < enqueueAmount; ++i)
1346 		build_queue_array[build_queue_count++] = unitId;
1347 }
1348 //----------- End of function FirmHarbor::add_queue -----------//
1349 
1350 
1351 //--------- Begin of function FirmHarbor::remove_queue ---------//
remove_queue(int unitId,int amount)1352 void FirmHarbor::remove_queue(int unitId, int amount)
1353 {
1354 	err_when(amount < 1);
1355 	if (amount < 1) return;
1356 
1357 	for( int i=build_queue_count-1 ; i>=0 ; i-- )
1358 	{
1359 		if( build_queue_array[i] == unitId )
1360 		{
1361 			err_when( build_queue_count > MAX_BUILD_SHIP_QUEUE );
1362 
1363 			misc.del_array_rec( build_queue_array, build_queue_count, sizeof(build_queue_array[0]), i+1 );
1364 
1365 			build_queue_count--;
1366 			amount--;
1367 
1368 			if (amount <= 0) return;
1369 		}
1370 	}
1371 
1372 	// If there were less units of unitId in the queue than were requested to be removed then
1373 	// also cancel build unit
1374 	if(build_unit_id==unitId)
1375 		cancel_build_unit();
1376 }
1377 //----------- End of function FirmHarbor::remove_queue -----------//
1378 
1379 
1380 //-------- Begin of static function put_ship_rec --------//
1381 //
put_ship_rec(int recNo,int x,int y,int refreshFlag)1382 static void put_ship_rec(int recNo, int x, int y, int refreshFlag)
1383 {
1384 	UnitMarine* unitPtr  = (UnitMarine*) unit_array[ firm_harbor_ptr->ship_recno_array[recNo-1] ];
1385 	UnitInfo*   unitInfo = unit_res[unitPtr->unit_id];
1386 
1387 	//-------- display unit icon -------//
1388 
1389 	vga_front.d3_panel_down(x+1, y+1, x+UNIT_SMALL_ICON_WIDTH+4, y+UNIT_SMALL_ICON_HEIGHT+4, 2, 0 );
1390 	// ###### begin Gilbert 17/10 #######//
1391 	vga_front.put_bitmap(x+3, y+3, unit_res[unitPtr->unit_id]->get_small_icon_ptr(unitPtr->rank_id) );
1392 	// ###### end Gilbert 17/10 #######//
1393 
1394 	y+=6;
1395 
1396 	//---------- display unit name ----------//
1397 
1398 	font_san.put( x+32 , y, _(unitInfo->name), 1, x+119 );		// 1-use short words
1399 
1400 	//------- display unit hit points -------//
1401 
1402 	String str;
1403 
1404 	str  = (int) unitPtr->hit_points;
1405 	str += "/";
1406 	str += unitPtr->max_hit_points;
1407 
1408 	font_san.put( x+125, y, str, 1, x+browse_ship.rec_width-3 );
1409 }
1410 //----------- End of static function put_ship_rec -----------//
1411 
1412