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