1 #include <stdio.h>
2 #include "lcconfig.h"
3 #include "lcstring.h"
4 #include "geometry.h"
5 #include "module_buttons.h"
6 #include "cliglobs.h"
7 #include "mouse.h"
8 #include "lcintl.h"
9 #include "lctypes.h"
10 #include "lclib.h"
11 #include "lchelp.h"
12
13 #define DEBUG_MODULES 0
14
15 static int module_rows;
16 static int module_cols;
17
18 static Mouse_Handle * mhandle;
19
20 static Rect * mbw = &scr.module_buttons;
21
22 int module_type[NUMOF_MODULES];
23 char *module_graphic[NUMOF_MODULES];
24 int module_tflag[NUMOF_MODULES];
25 char module_help[NUMOF_MODULES][20];
26
27 int module_help_flag[NUMOF_MODULES];
28
29 int sbut[NUMOF_MODULES];
30
31 int selected_module = 0;
32 int selected_module_type;
33 int selected_module_group;
34 int selected_module_cost;
35
36
37 void
init_modules(void)38 init_modules (void)
39 {
40 int i;
41
42 /* Get max number of rows for space allotted */
43 module_rows = (mbw->h / (SELECT_BUTTON_INTERVAL));
44 module_cols = (mbw->w / (SELECT_BUTTON_INTERVAL));
45
46 /* Tell the mouse where we are */
47 mhandle = mouse_register(&scr.module_buttons,&module_buttons_handler);
48
49 #if (DEBUG_MODULES)
50 printf("debug_modules:\t\tr=%d\tc=%d\n",module_rows, module_cols);
51 #endif
52
53 /* sbut converts a group into a column major index of the button array. */
54 sbut[0] = 16; /* buldoze */
55 sbut[1] = 13; /* powerline */
56 sbut[2] = 15; /* solar power */
57 sbut[3] = 14; /* substation */
58 sbut[4] = 0; /* residence */
59 sbut[5] = 1; /* farm */
60 sbut[6] = 2; /* market */
61 sbut[7] = 19; /* track */
62 sbut[8] = 10; /* coalmine */
63 sbut[9] = 28; /* rail */
64 sbut[10] = 29; /* coal power */
65 sbut[11] = 25; /* road */
66 sbut[12] = 27; /* light industry */
67 sbut[13] = 11; /* university */
68 sbut[14] = 3; /* commune */
69 sbut[15] = 4; /* oremine */
70 sbut[16] = 5; /* tip */
71 sbut[17] = 9; /* export */
72 sbut[18] = 12; /* heavy industry */
73 sbut[19] = 6; /* parkland */
74 sbut[20] = 30; /* recycle */
75 sbut[21] = 20; /* water */
76 sbut[22] = 26; /* health */
77 sbut[23] = 31; /* rocket */
78 sbut[24] = 24; /* windmill */
79 sbut[25] = 17; /* monument */
80 sbut[26] = 21; /* school */
81 sbut[27] = 22; /* blacksmith */
82 sbut[28] = 8; /* mill */
83 sbut[29] = 18; /* pottery */
84 sbut[30] = 23; /* fire station */
85 sbut[31] = 7; /* cricket */
86
87
88 /* load graphics and initialize help */
89
90 module_graphic[sbut[0]] = load_graphic ("buldoze-button.csi");
91 module_type[sbut[0]] = CST_GREEN;
92 strcpy (module_help[sbut[0]], "bulldoze.hlp");
93
94 module_graphic[sbut[1]] = load_graphic ("powerline-button.csi");
95 module_type[sbut[1]] = CST_POWERL_H_L;
96 strcpy (module_help[sbut[1]], "powerline.hlp");
97
98 module_graphic[sbut[2]] = load_graphic ("powerssolar-button.csi");
99 module_type[sbut[2]] = CST_POWERS_SOLAR;
100 strcpy (module_help[sbut[2]], "powerssolar.hlp");
101
102 module_graphic[sbut[3]] = load_graphic ("substation-button.csi");
103 module_type[sbut[3]] = CST_SUBSTATION_R;
104 strcpy (module_help[sbut[3]], "substation.hlp");
105
106 module_graphic[sbut[4]] = load_graphic ("residence-button.csi");
107 module_type[sbut[4]] = CST_RESIDENCE_LL;
108 strcpy (module_help[sbut[4]], "residential.hlp");
109
110 module_graphic[sbut[5]] = load_graphic ("organic-farm-button.csi");
111 module_type[sbut[5]] = CST_FARM_O0;
112 strcpy (module_help[sbut[5]], "farm.hlp");
113
114 module_graphic[sbut[6]] = load_graphic ("market-button.csi");
115 module_type[sbut[6]] = CST_MARKET_EMPTY;
116 strcpy (module_help[sbut[6]], "market.hlp");
117
118 module_help_flag[sbut[7]] = 1; /* No help for track */
119 module_graphic[sbut[7]] = load_graphic ("track-button.csi");
120 module_type[sbut[7]] = CST_TRACK_LR;
121 strcpy (module_help[sbut[7]], "track.hlp");
122
123 module_graphic[sbut[8]] = load_graphic ("coalmine-button.csi");
124 module_type[sbut[8]] = CST_COALMINE_EMPTY;
125 strcpy (module_help[sbut[8]], "coalmine.hlp");
126
127 module_graphic[sbut[9]] = load_graphic ("rail-button.csi");
128 module_type[sbut[9]] = CST_RAIL_LR;
129 strcpy (module_help[sbut[9]], "rail.hlp");
130
131 module_graphic[sbut[10]] = load_graphic ("powerscoal-button.csi");
132 module_type[sbut[10]] = CST_POWERS_COAL_EMPTY;
133 strcpy (module_help[sbut[10]], "powerscoal.hlp");
134
135 module_graphic[sbut[11]] = load_graphic ("road-button.csi");
136 module_type[sbut[11]] = CST_ROAD_LR;
137 strcpy (module_help[sbut[11]], "road.hlp");
138
139 module_graphic[sbut[12]] = load_graphic ("industryl-button.csi");
140 module_type[sbut[12]] = CST_INDUSTRY_L_C;
141 strcpy (module_help[sbut[12]], "industryl.hlp");
142
143 module_graphic[sbut[13]] = load_graphic ("university-button.csi");
144 module_type[sbut[13]] = CST_UNIVERSITY;
145 strcpy (module_help[sbut[13]], "university.hlp");
146
147 module_graphic[sbut[14]] = load_graphic ("commune-button.csi");
148 module_type[sbut[14]] = CST_COMMUNE_1;
149 strcpy (module_help[sbut[14]], "commune.hlp");
150
151 module_graphic[sbut[15]] = load_graphic ("oremine-button.csi");
152 module_type[sbut[15]] = CST_OREMINE_1;
153 strcpy (module_help[sbut[15]], "oremine.hlp");
154
155 module_graphic[sbut[16]] = load_graphic ("tip-button.csi");
156 module_type[sbut[16]] = CST_TIP_0;
157 strcpy (module_help[sbut[16]], "tip.hlp");
158
159 module_graphic[sbut[17]] = load_graphic ("port-button.csi");
160 module_type[sbut[17]] = CST_EX_PORT;
161 strcpy (module_help[sbut[17]], "port.hlp");
162
163 module_graphic[sbut[18]] = load_graphic ("industryh-button.csi");
164 module_type[sbut[18]] = CST_INDUSTRY_H_C;
165 strcpy (module_help[sbut[18]], "industryh.hlp");
166
167 module_graphic[sbut[19]] = load_graphic ("parkland-button.csi");
168 module_type[sbut[19]] = CST_PARKLAND_PLANE;
169 strcpy (module_help[sbut[19]], "park.hlp");
170
171 module_graphic[sbut[20]] = load_graphic ("recycle-button.csi");
172 module_type[sbut[20]] = CST_RECYCLE;
173 strcpy (module_help[sbut[20]], "recycle.hlp");
174
175 module_graphic[sbut[21]] = load_graphic ("water-button.csi");
176 module_type[sbut[21]] = CST_WATER;
177 strcpy (module_help[sbut[21]], "river.hlp");
178
179 module_graphic[sbut[22]] = load_graphic ("health-button.csi");
180 module_type[sbut[22]] = CST_HEALTH;
181 strcpy (module_help[sbut[22]], "health.hlp");
182
183 module_graphic[sbut[23]] = load_graphic ("rocket-button.csi");
184 module_type[sbut[23]] = CST_ROCKET_1;
185 strcpy (module_help[sbut[23]], "rocket.hlp");
186
187 module_graphic[sbut[24]] = load_graphic ("windmill-button.csi");
188 module_type[sbut[24]] = CST_WINDMILL_1_R;
189 strcpy (module_help[sbut[24]], "windmill.hlp");
190
191 module_graphic[sbut[25]] = load_graphic ("monument-button.csi");
192 module_type[sbut[25]] = CST_MONUMENT_0;
193 strcpy (module_help[sbut[25]], "monument.hlp");
194
195 module_graphic[sbut[26]] = load_graphic ("school-button.csi");
196 module_type[sbut[26]] = CST_SCHOOL;
197 strcpy (module_help[sbut[26]], "school.hlp");
198
199 module_graphic[sbut[27]] = load_graphic ("blacksmith-button.csi");
200 module_type[sbut[27]] = CST_BLACKSMITH_0;
201 strcpy (module_help[sbut[27]], "blacksmith.hlp");
202
203 module_graphic[sbut[28]] = load_graphic ("mill-button.csi");
204 module_type[sbut[28]] = CST_MILL_0;
205 strcpy (module_help[sbut[28]], "mill.hlp");
206
207 module_graphic[sbut[29]] = load_graphic ("pottery-button.csi");
208 module_type[sbut[29]] = CST_POTTERY_0;
209 strcpy (module_help[sbut[29]], "pottery.hlp");
210
211 module_graphic[sbut[30]] = load_graphic ("firestation-button.csi");
212 module_type[sbut[30]] = CST_FIRESTATION_1;
213 strcpy (module_help[sbut[30]], "firestation.hlp");
214
215 module_graphic[sbut[31]] = load_graphic ("cricket-button.csi");
216 module_type[sbut[31]] = CST_CRICKET_1;
217 strcpy (module_help[sbut[31]], "cricket.hlp");
218
219
220
221 /* disable all the buttons */
222 for (i = 0; i < NUMOF_MODULES; i++) {
223 module_tflag[i] = 0;
224 }
225
226 /* select track (which will be enabled later) */
227 #if defined (commentout)
228 selected_module_type = CST_TRACK_LR;
229 selected_module_cost = GROUP_TRACK_COST;
230 selected_module_group = get_group_of_type(selected_module_type);
231 #endif
232 selected_module = sbut[7];
233 /* GCS: Move to later in initialization because I don't want to draw_main_window_box() yet */
234 #if defined (commentout)
235 set_selected_module (CST_TRACK_LR);
236 #endif
237 }
238
239
240 /* update_avail_modules: Determine which modules are available, based on
241 tech level */
242
243 void
update_avail_modules(int popup)244 update_avail_modules (int popup)
245 {
246 int i;
247 int f; /* remembers if a change is made to what is available, so we can
248 draw if necessary */
249
250 for (i = 0; i < NUMOF_MODULES; i++)
251 {
252 int g = inv_sbut(i);
253 f = module_tflag[i];
254 if (tech_level >= main_groups[g].tech * MAX_TECH_LEVEL/1000)
255 {
256 if (module_tflag[i] == 0)
257 if (popup)
258 activate_module (i);
259 f = 1;
260 }
261 else if (module_tflag[i] != 0 &&
262 tech_level
263 < ((main_groups[g].tech - (main_groups[g].tech/10)) * MAX_TECH_LEVEL/1000) )
264 f = 0;
265 if (module_tflag[i] != f)
266 {
267 module_tflag[i] = f;
268 draw_module (i, module_graphic[i]);
269 }
270 }
271 /* XXX: Why is this here? Should be with rest of tech gained messages! */
272 /* GCS: Because the modern windmill tech reuses the same module number
273 as the primative windmill? */
274 if (tech_level > MODERN_WINDMILL_TECH && modern_windmill_flag == 0)
275 {
276 ok_dial_box ("mod_wind_up.mes", GOOD, 0L);
277 modern_windmill_flag = 1;
278 }
279 }
280
281 /* Display message for module when it is activated (see above) */
282
283 void
activate_module(int module)284 activate_module (int module)
285 {
286 module = inv_sbut (module);
287
288 if (module == GROUP_WINDMILL)
289 ok_dial_box ("windmillup.mes", GOOD, 0L);
290 else if (module == GROUP_COAL_POWER)
291 ok_dial_box ("coalpowerup.mes", GOOD, 0L);
292 /* else if (module == (GROUP_SOLAR_POWER - 1)) */
293 else if (module == GROUP_SOLAR_POWER)
294 ok_dial_box ("solarpowerup.mes", GOOD, 0L);
295 else if (module == GROUP_COALMINE)
296 ok_dial_box ("coalmineup.mes", GOOD, 0L);
297 else if (module == GROUP_RAIL)
298 ok_dial_box ("railwayup.mes", GOOD, 0L);
299 else if (module == GROUP_ROAD)
300 ok_dial_box ("roadup.mes", GOOD, 0L);
301 else if (module == GROUP_INDUSTRY_L)
302 ok_dial_box ("ltindustryup.mes", GOOD, 0L);
303 else if (module == GROUP_UNIVERSITY)
304 ok_dial_box ("universityup.mes", GOOD, 0L);
305 else if (module == GROUP_OREMINE)
306 {
307 if (GROUP_OREMINE_TECH > 0)
308 ok_dial_box ("oremineup.mes", GOOD, 0L);
309 }
310 else if (module == GROUP_PORT) /* exports are the same */
311 ok_dial_box ("import-exportup.mes", GOOD, 0L);
312 else if (module == GROUP_INDUSTRY_H)
313 ok_dial_box ("hvindustryup.mes", GOOD, 0L);
314 else if (module == GROUP_PARKLAND)
315 {
316 if (GROUP_PARKLAND_TECH > 0)
317 ok_dial_box ("parkup.mes", GOOD, 0L);
318 }
319 else if (module == GROUP_RECYCLE)
320 ok_dial_box ("recycleup.mes", GOOD, 0L);
321 else if (module == GROUP_RIVER)
322 {
323 if (GROUP_WATER_TECH > 0)
324 ok_dial_box ("riverup.mes", GOOD, 0L);
325 }
326 else if (module == GROUP_HEALTH)
327 ok_dial_box ("healthup.mes", GOOD, 0L);
328 else if (module == GROUP_ROCKET)
329 ok_dial_box ("rocketup.mes", GOOD, 0L);
330 else if (module == GROUP_SCHOOL)
331 {
332 if (GROUP_SCHOOL_TECH > 0)
333 ok_dial_box ("schoolup.mes", GOOD, 0L);
334 }
335 else if (module == GROUP_BLACKSMITH)
336 {
337 if (GROUP_BLACKSMITH_TECH > 0)
338 ok_dial_box ("blacksmithup.mes", GOOD, 0L);
339 }
340 else if (module == GROUP_MILL)
341 {
342 if (GROUP_MILL_TECH > 0)
343 ok_dial_box ("millup.mes", GOOD, 0L);
344 }
345 else if (module == GROUP_POTTERY)
346 {
347 if (GROUP_POTTERY_TECH > 0)
348 ok_dial_box ("potteryup.mes", GOOD, 0L);
349 }
350 else if (module == GROUP_FIRESTATION)
351 ok_dial_box ("firestationup.mes", GOOD, 0L);
352 else if (module == GROUP_CRICKET)
353 ok_dial_box ("cricketup.mes", GOOD, 0L);
354 }
355
356
357 /* handle_module_buttons: mouse handler for module window */
358
359 void
module_buttons_handler(int x,int y,int mbutton)360 module_buttons_handler (int x, int y, int mbutton)
361 {
362 int module;
363 int row, col;
364
365
366 /* Figure out which row and column the click came in */
367 row = (y / (SELECT_BUTTON_INTERVAL));
368 if ((y % SELECT_BUTTON_INTERVAL) <= 8)
369 return; /* in the gap */
370
371 col = (x / (SELECT_BUTTON_INTERVAL));
372 if ((x % SELECT_BUTTON_INTERVAL) <= 8)
373 return;
374
375 module = row + (module_rows * col);
376
377 select_module (module, mbutton);
378 }
379
380
381 /* select_module: low level click handler; display help or change to
382 module, depending on mbutton (right or left click) */
383
384 void
select_module(int module,int mbutton)385 select_module (int module, int mbutton)
386 {
387 if (module_tflag[module] == 0 && mbutton != LC_MOUSE_RIGHTBUTTON) {
388 ok_dial_box ("not_enough_tech.mes", BAD, 0L);
389 return;
390 }
391 if (mbutton == LC_MOUSE_RIGHTBUTTON
392 || (module_help_flag[module] == 0
393 && !suppress_firsttime_module_help))
394 {
395 activate_help (module_help[module]);
396 if (mbutton != LC_MOUSE_RIGHTBUTTON)
397 module_help_flag[module] = 1;
398 if (mbutton == LC_MOUSE_RIGHTBUTTON)
399 return;
400 }
401
402 unhighlight_module_button (selected_module);
403 highlight_module_button (module);
404 selected_module = module;
405
406 set_selected_module (module_type[module]);
407 }
408
409
410 /* highlight_module_button: draw a nice border around a selected module */
411
412 void
highlight_module_button(int module)413 highlight_module_button (int module)
414 {
415 int x, y;
416 int row, col;
417
418 if (module == 0) {
419 row = 0;
420 col = 0;
421 } else {
422 row = module % module_rows;
423 col = module / module_rows;
424 }
425
426 x = 8 + (col * 24) + mbw->x;
427 y = 8 + (row * 24) + mbw->y;
428
429 hide_mouse ();
430 draw_small_bezel(x + 1, y + 1,
431 SELECT_BUTTON_WIDTH - 2, SELECT_BUTTON_WIDTH - 2,
432 yellow(0));
433 redraw_mouse ();
434 }
435
436
437 /* unhighlight_module_button: replace highlight border with regular one */
438
439 void
unhighlight_module_button(int module)440 unhighlight_module_button (int module)
441 {
442 int x, y;
443
444 int row, col;
445
446 if (module == 0) {
447 row = 0;
448 col = 0;
449 } else {
450 row = module % module_rows;
451 col = module / module_rows;
452 }
453
454 x = 8 + (col * 24) + mbw->x;
455 y = 8 + (row * 24) + mbw->y;
456
457 hide_mouse ();
458 draw_small_bezel(x + 1, y + 1,
459 SELECT_BUTTON_WIDTH - 2, SELECT_BUTTON_WIDTH - 2,
460 blue(0));
461 redraw_mouse ();
462 }
463
464
465 /* draw_selected_module_cost: write info about the module to the status area */
466
467 void
draw_selected_module_cost()468 draw_selected_module_cost ()
469 {
470 Rect* b = &scr.select_message;
471 char s[100];
472 char coststr[20];
473 char bldzstr[20];
474
475 selected_module_cost = get_type_cost (selected_module_type);
476
477 commify(coststr,20,selected_module_cost);
478 commify(bldzstr,20,main_groups[selected_module_group].bul_cost);
479
480 if (selected_module_group == GROUP_BARE)
481 snprintf (s, 100, _("Bulldoze - cost varies"));
482 else
483 snprintf (s, 100, _("%s %s Bulldoze %s"),
484 _(main_groups[selected_module_group].name),
485 coststr, bldzstr);
486
487 Fgl_fillbox (b->x, b->y, 42 * 8, 8, TEXT_BG_COLOUR);
488 Fgl_write (b->x, b->y, s);
489 }
490
491
492 /* draw_modules: fill a box and then draw all graphics */
493
494 void
draw_modules(void)495 draw_modules (void)
496 {
497 int i;
498 Fgl_fillbox (mbw->x, mbw->y, mbw->w, mbw->h, white (20));
499
500 for (i = 0; i < NUMOF_MODULES; i++)
501 draw_module (sbut[i], module_graphic[sbut[i]]);
502
503 highlight_module_button(selected_module);
504
505 }
506
507 void
draw_module(int module,char * graphic)508 draw_module (int module, char *graphic)
509 {
510 int x, y, xx, yy;
511 int row, col;
512
513 if (module == 0) {
514 row = 0;
515 col = 0;
516 } else {
517 row = module % module_rows;
518 col = module / module_rows;
519 }
520
521 x = 8 + (col * 24);
522 y = 8 + (row * 24);
523
524 hide_mouse ();
525
526 Fgl_putbox (x + mbw->x, y + mbw->y, 16, 16, graphic);
527 unhighlight_module_button (module);
528
529 /* Modules we don't have enough tech for are greyed out. */
530 if (module_tflag[module] == 0)
531 {
532 for (yy = -3; yy < 19; yy++)
533 for (xx = -3; xx < 19; xx += 2)
534 Fgl_setpixel (x + xx + (yy % 2) + mbw->x,
535 y + yy + mbw->y, white (15));
536 }
537 redraw_mouse ();
538 }
539
540
541 /* inv_sbut: the order and the number of the module aren't the same;
542 inv_sbut converts between a geographical location and an array location */
543
544 int
inv_sbut(int button)545 inv_sbut (int button)
546 {
547 int i, j;
548 for (i = 0; i < 32; i++)
549 if (sbut[i] == button)
550 {
551 j = i;
552 return (j);
553 }
554 /* XXX: do we need this debug stuff? */
555 /* GCS: This is a fatal error. Probably OK. */
556 printf ("Button=%d\n", button);
557 for (i = 0; i < 32; i++)
558 printf ("%5d", sbut[i]);
559 printf ("\n");
560 do_error ("An inv_sbut error has happened.");
561 return (-1); /* can't get here */
562 }
563
564 void
set_selected_module(int type)565 set_selected_module (int type)
566 {
567 selected_module_type = type;
568 selected_module_group = get_group_of_type(selected_module_type);
569 if (selected_module_type == CST_RESIDENCE_LL) {
570 choose_residence ();
571 }
572
573 #ifdef LC_X11 /* XXX: WCK: shouldn't be any platform specific code here */
574 if (selected_module_group == GROUP_BARE)
575 XDefineCursor (display.dpy, display.win, pirate_cursor);
576 else
577 XDefineCursor (display.dpy, display.win, None);
578 #endif
579
580 draw_selected_module_cost();
581
582 if (selected_module_type == CST_GREEN) {
583 draw_main_window_box (red (8));
584 } else {
585 draw_main_window_box (green (8));
586 monument_bul_flag = 0;
587 river_bul_flag = 0;
588 shanty_bul_flag = 0;
589 }
590
591
592 selected_module_type = type;
593 selected_module_group = get_group_of_type(selected_module_type);
594 draw_selected_module_cost (); /* sets module cost */
595 }
596