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_MINE.CPP
22 //Description : Firm Mine
23 
24 #include <OINFO.h>
25 #include <OVGA.h>
26 #include <vga_util.h>
27 #include <OSTR.h>
28 #include <OFONT.h>
29 #include <ONEWS.h>
30 #include <OUNIT.h>
31 #include <ORACERES.h>
32 #include <OGAME.h>
33 #include <OWORLD.h>
34 #include <ONATION.h>
35 #include <OSITE.h>
36 #include <OF_MINE.h>
37 #include <OF_FACT.h>
38 #include <OBUTT3D.h>
39 #include "gettext.h"
40 
41 //------- define static vars -------//
42 
43 static Button3D	button_vacate_firm;
44 
45 //--------- Begin of function FirmMine::FirmMine ---------//
46 //
FirmMine()47 FirmMine::FirmMine()
48 {
49 	firm_skill_id = SKILL_MINING;
50 
51 	cur_month_production = (float) 0;
52 	last_month_production = (float) 0;
53 
54 	next_output_link_id	  = 0;
55 	next_output_firm_recno = 0;
56 
57 	ai_should_build_factory_count = 0;
58 }
59 //----------- End of function FirmMine::FirmMine -----------//
60 
61 
62 //--------- Begin of function FirmMine::~FirmMine ---------//
63 //
~FirmMine()64 FirmMine::~FirmMine()
65 {
66 	//------- update the site deposit reserve ------//
67 
68 	if( site_recno )
69 	{
70 		site_array.untapped_raw_count++;
71 
72 		if( reserve_qty==0 )		// if the reserve has been used up
73 		{
74 			site_array.del_site(site_recno);
75 		}
76 		else		// restore the site
77 		{
78 			Site* sitePtr = site_array[site_recno];
79 
80 			sitePtr->reserve_qty = (int) reserve_qty;
81 			sitePtr->has_mine 	= 0;
82 		}
83 	}
84 
85 	//-------- decrease AI raw count --------//
86 
87 	if( raw_id )
88 	{
89 		nation_array[nation_recno]->raw_count_array[raw_id-1]--;
90 
91 		err_when( nation_array[nation_recno]->raw_count_array[raw_id-1] < 0 );
92 	}
93 }
94 //----------- End of function FirmMine::~FirmMine -----------//
95 
96 
97 //--------- Begin of function FirmMine::init_derived ---------//
98 //
init_derived()99 void FirmMine::init_derived()
100 {
101 	//---- scan for raw site in this firm's building location ----//
102 
103 	Location* locPtr = scan_raw_site();
104 
105 	if( locPtr )
106 	{
107 		site_recno  = locPtr->site_recno();
108 		raw_id		= site_array[site_recno]->object_id;
109 		reserve_qty = (float) site_array[site_recno]->reserve_qty;
110 
111 		site_array[site_recno]->has_mine = 1;
112 		site_array.untapped_raw_count--;
113 
114 		err_when( site_array.untapped_raw_count < 0 );
115 	}
116 	else
117 	{
118 		site_recno 	= 0;
119 		raw_id 		= 0;
120 		reserve_qty = (float) 0;
121 	}
122 
123 	stock_qty 	 	= (float) 0;
124 	max_stock_qty  = (float) DEFAULT_MINE_MAX_STOCK_QTY;
125 
126 	//-------- increase AI raw count --------//
127 
128 	if( raw_id )
129 		nation_array[nation_recno]->raw_count_array[raw_id-1]++;
130 }
131 //----------- End of function FirmMine::init_derived -----------//
132 
133 
134 //------- Begin of function FirmMine::change_nation ---------//
135 //
change_nation(int newNationRecno)136 void FirmMine::change_nation(int newNationRecno)
137 {
138 	if( raw_id )
139 	{
140 		nation_array[nation_recno]->raw_count_array[raw_id-1]--;
141 
142 		err_when( nation_array[nation_recno]->raw_count_array[raw_id-1] < 0 );
143 
144 		nation_array[newNationRecno]->raw_count_array[raw_id-1]++;
145 	}
146 
147 	//-------- change the nation of this firm now ----------//
148 
149 	Firm::change_nation(newNationRecno);
150 }
151 //-------- End of function FirmMine::change_nation ---------//
152 
153 
154 //--------- Begin of function FirmMine::scan_raw_site ---------//
155 //
scan_raw_site()156 Location* FirmMine::scan_raw_site()
157 {
158 	//---- scan for raw site in this firm's building location ----//
159 
160 	int xLoc, yLoc;
161 	Location* locPtr;
162 
163 	for( yLoc=loc_y1 ; yLoc<=loc_y2 ; yLoc++ )
164 	{
165 		for( xLoc=loc_x1 ; xLoc<=loc_x2 ; xLoc++ )
166 		{
167 			locPtr = world.get_loc(xLoc,yLoc);
168 
169 			if( locPtr->has_site() &&
170 				 site_array[locPtr->site_recno()]->site_type == SITE_RAW )
171 			{
172 				return locPtr;
173 			}
174 		}
175 	}
176 
177 	return NULL;
178 }
179 //--------- End of function FirmMine::scan_raw_site ---------//
180 
181 
182 //--------- Begin of function FirmMine::put_info ---------//
183 //
put_info(int refreshFlag)184 void FirmMine::put_info(int refreshFlag)
185 {
186 	disp_basic_info(INFO_Y1, refreshFlag);
187 
188 	if( !should_show_info() )
189 		return;
190 
191 	disp_mine_info(INFO_Y1+52, refreshFlag);
192 	disp_worker_list(INFO_Y1+127, refreshFlag);
193 	disp_worker_info(INFO_Y1+191, refreshFlag);
194 
195 	//------ display mobilize button -------//
196 
197 	int x = INFO_X1;
198 
199 	if (own_firm())
200 	{
201 		if (refreshFlag == INFO_REPAINT)
202 		{
203 			button_vacate_firm.paint(INFO_X1, INFO_Y1 + 249, 'A', "RECRUIT");
204 			button_vacate_firm.set_help_code("MOBILIZE");
205 		}
206 
207 		if( have_own_workers() )
208 			button_vacate_firm.enable();
209 		else
210 			button_vacate_firm.disable();
211 
212 		x += BUTTON_ACTION_WIDTH;
213 	}
214 
215 	//---------- display spy button ----------//
216 
217 	disp_spy_button(x, INFO_Y1+249, refreshFlag);
218 }
219 //----------- End of function FirmMine::put_info -----------//
220 
221 
222 //--------- Begin of function FirmMine::detect_info ---------//
223 //
detect_info()224 int FirmMine::detect_info()
225 {
226 	//-------- detect basic info -----------//
227 
228 	if( detect_basic_info() )
229 		return 1;
230 
231 	//----------- detect worker -----------//
232 
233 	if( detect_worker_list() )
234 	{
235 		disp_mine_info(INFO_Y1+52, INFO_UPDATE);
236 		disp_worker_info(INFO_Y1+191, INFO_UPDATE);
237 		return 1;
238 	}
239 
240 	//-------- detect spy button ----------//
241 
242 	if( detect_spy_button() )
243 		return 1;
244 
245 	if( !own_firm() )
246 		return 0;
247 
248 	//-------- detect mobilize button ----------//
249 
250 	if (button_vacate_firm.detect())
251 	{
252 		mobilize_all_workers(COMMAND_PLAYER);
253 		return 1;
254 	}
255 
256 	return 0;
257 }
258 //----------- End of function FirmMine::detect_info -----------//
259 
260 
261 const char *mining_raw_msg[MAX_RAW] =
262 {
263 	N_("Mining Clay"),
264 	N_("Mining Copper"),
265 	N_("Mining Iron"),
266 };
267 //--------- Begin of function FirmMine::disp_mine_info ---------//
268 //
disp_mine_info(int dispY1,int refreshFlag)269 void FirmMine::disp_mine_info(int dispY1, int refreshFlag)
270 {
271 	//---------------- paint the panel --------------//
272 
273 	if( refreshFlag == INFO_REPAINT )
274 		vga_util.d3_panel_up( INFO_X1, dispY1, INFO_X2, dispY1+70);
275 
276 	//------ if there is no natural resource on this location ------//
277 
278 	if( !raw_id )
279 	{
280 		font_san.center_put( INFO_X1, dispY1, INFO_X2, dispY1+70, _("No Natural Resources") );
281 		return;
282 	}
283 
284 	//-------------- display mining info -----------//
285 
286 	int x=INFO_X1+4, y=dispY1+4;
287 
288 	raw_res.put_small_raw_icon( x+1, y+1, raw_id );
289 
290 	String str;
291 
292 	str = _(mining_raw_msg[raw_id-1]);
293 
294 	font_san.disp( x+20, y, str, INFO_X2-2);
295 	y+=16;
296 
297 	font_san.field( x, y, _("Monthly Production"), x+126, (int) production_30days(), 1, INFO_X2-2, refreshFlag, "MN_PROD");
298 	y+=16;
299 
300 	str  = (int) stock_qty;
301 	str += " / ";
302 	str += (int) max_stock_qty;
303 
304 	font_san.field( x, y, _("Mined Stock"), x+126, str, INFO_X2-2, refreshFlag, "MN_STOCK");
305 	y+=16;
306 
307 	font_san.field( x, y, _("Untapped Reserve"), x+126, (int) reserve_qty, 1, INFO_X2-2, refreshFlag, "MN_UNTAP");
308 }
309 //----------- End of function FirmMine::disp_mine_info -----------//
310 
311 
312 //--------- Begin of function FirmMine::next_day ---------//
313 //
next_day()314 void FirmMine::next_day()
315 {
316 	//----- call next_day() of the base class -----//
317 
318 	Firm::next_day();
319 
320 	//----------- update population -------------//
321 
322 	recruit_worker();
323 
324 	//-------- train up the skill ------------//
325 
326 	update_worker();
327 
328 	//---------------------------------------//
329 
330 	if( info.game_date%PROCESS_GOODS_INTERVAL == firm_recno%PROCESS_GOODS_INTERVAL )		// produce raw materials once every 3 days
331 	{
332 		produce_raw();
333 		set_next_output_firm();						// set next output firm
334 	}
335 }
336 //----------- End of function FirmMine::next_day -----------//
337 
338 
339 //--------- Begin of function FirmMine::next_month ---------//
340 //
next_month()341 void FirmMine::next_month()
342 {
343 	last_month_production = cur_month_production;
344 	cur_month_production  = (float) 0;
345 }
346 //----------- End of function FirmMine::next_month -----------//
347 
348 
349 //------- Begin of function FirmMine::set_next_output_firm ------//
350 //
351 // Set next_output_firm_recno, the recno of the linked firm
352 // to which this mine is going to output raw materials.
353 //
set_next_output_firm()354 void FirmMine::set_next_output_firm()
355 {
356 	int i, firmRecno, firmId;
357 
358 	for( i=0 ; i<linked_firm_count ; i++ )		// MAX tries
359 	{
360 		if( ++next_output_link_id > linked_firm_count )    // next firm in the link
361 			next_output_link_id = 1;
362 
363 		if( linked_firm_enable_array[next_output_link_id-1] == LINK_EE )
364 		{
365 			firmRecno = linked_firm_array[next_output_link_id-1];
366 			firmId 	 = firm_array[firmRecno]->firm_id;
367 
368 			if( firmId==FIRM_FACTORY || firmId==FIRM_MARKET )
369 			{
370 				next_output_firm_recno = firmRecno;
371 				return;
372 			}
373 		}
374 	}
375 
376 	next_output_firm_recno = 0;		// this mine has no linked output firms
377 }
378 //-------- End of function FirmMine::set_next_output_firm ---------//
379 
380 
381 //--------- Begin of function FirmMine::produce_raw ---------//
382 //
383 // Produce raw materials.
384 //
produce_raw()385 void FirmMine::produce_raw()
386 {
387 	//----- if stock capacity reached or reserve exhausted -----//
388 
389 	if( stock_qty == max_stock_qty || reserve_qty==0 )
390 		return;
391 
392 	err_when( reserve_qty < 0 );
393 	err_when( stock_qty > max_stock_qty );
394 
395 	//------- calculate the productivity of the workers -----------//
396 
397 	calc_productivity();
398 
399 	//-------- mine raw materials -------//
400 
401 	float produceQty = (float) 100 * productivity / 100;
402 
403 	produceQty = MIN( produceQty, reserve_qty );
404 	produceQty = MIN( produceQty, max_stock_qty-stock_qty );
405 
406 	reserve_qty -= produceQty;
407 	stock_qty	+= produceQty;
408 
409 	cur_month_production += produceQty;
410 
411 	site_array[site_recno]->reserve_qty = (int) reserve_qty;		// update the reserve_qty in site_array
412 
413 	err_when( reserve_qty < 0 );
414 	err_when( stock_qty > max_stock_qty );
415 
416 	//---- add news if run out of raw deposit ----//
417 
418 	if( reserve_qty == 0 )
419 	{
420 		site_array.untapped_raw_count++;		// have to restore its first as del_site() will decrease uptapped_raw_count
421 
422 		site_array.del_site(site_recno);
423 		site_recno = 0;
424 
425 		if( nation_recno == nation_array.player_recno )
426 			news_array.raw_exhaust(raw_id, center_x, center_y);
427 	}
428 }
429 //----------- End of function FirmMine::produce_raw -----------//
430 
431 
432 //------- Begin of function FirmMine::draw -----------//
433 //
434 // Draw raw materials stocks.
435 //
draw(int displayLayer)436 void FirmMine::draw(int displayLayer)
437 {
438 	Firm::draw(displayLayer);
439 
440 	if( !should_show_info() )
441 		return;
442 
443 	if( under_construction )
444 		return;
445 
446 	if( raw_id && displayLayer == 1)
447 	{
448 		int cargoCount = MAX_CARGO	* (int)stock_qty / (int)max_stock_qty;
449 
450 		draw_cargo( MAX(1,cargoCount), raw_res.small_raw_icon(raw_id) );
451 	}
452 }
453 //--------- End of function FirmMine::draw -----------//
454 
455