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