1 /* ---------------------------------------------------------------------- *
2 * shrtypes.c
3 * This file is part of lincity.
4 * Lincity is copyright (c) I J Peters 1995-1997, (c) Greg Sharp 1997-2001.
5 * ---------------------------------------------------------------------- */
6 #include "lcconfig.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "lcstring.h"
10 #include "common.h"
11 #include "lctypes.h"
12 #include "lin-city.h"
13 #include "typeinit.h"
14 #include "cliglobs.h"
15 #include "engglobs.h"
16
17
18 void
set_mappoint_used(int fromx,int fromy,int x,int y)19 set_mappoint_used (int fromx, int fromy, int x, int y)
20 {
21 MP_TYPE(x,y) = CST_USED;
22 MP_GROUP(x,y) = GROUP_USED;
23 MP_INFO(x,y).int_1 = fromx;
24 MP_INFO(x,y).int_2 = fromy;
25 }
26
27
28 void
set_mappoint(int x,int y,short selected_type)29 set_mappoint (int x, int y, short selected_type)
30 {
31 int grp;
32
33 if ((grp = get_group_of_type(selected_type)) < 0) return;
34
35 MP_TYPE(x,y) = selected_type;
36 MP_GROUP(x,y) = grp;
37
38 if (main_groups[grp].size == 2)
39 {
40 set_mappoint_used (x, y, x + 1, y);
41 set_mappoint_used (x, y, x, y + 1);
42 set_mappoint_used (x, y, x + 1, y + 1);
43 }
44 else if (main_groups[grp].size == 3)
45 {
46 set_mappoint_used (x, y, x + 1, y);
47 set_mappoint_used (x, y, x + 2, y);
48 set_mappoint_used (x, y, x + 1, y + 1);
49 set_mappoint_used (x, y, x + 2, y + 1);
50 set_mappoint_used (x, y, x + 1, y + 2);
51 set_mappoint_used (x, y, x + 2, y + 2);
52 set_mappoint_used (x, y, x, y + 1);
53 set_mappoint_used (x, y, x, y + 2);
54 }
55 else if (main_groups[grp].size == 4)
56 {
57 set_mappoint_used (x, y, x + 1, y);
58 set_mappoint_used (x, y, x + 2, y);
59 set_mappoint_used (x, y, x + 1, y + 1);
60 set_mappoint_used (x, y, x + 2, y + 1);
61 set_mappoint_used (x, y, x + 1, y + 2);
62 set_mappoint_used (x, y, x + 2, y + 2);
63 set_mappoint_used (x, y, x, y + 1);
64 set_mappoint_used (x, y, x, y + 2);
65
66 set_mappoint_used (x, y, x + 3, y);
67 set_mappoint_used (x, y, x + 3, y + 1);
68 set_mappoint_used (x, y, x + 3, y + 2);
69 set_mappoint_used (x, y, x + 3, y + 3);
70 set_mappoint_used (x, y, x, y + 3);
71 set_mappoint_used (x, y, x + 1, y + 3);
72 set_mappoint_used (x, y, x + 2, y + 3);
73 }
74 }
75
76
77 void
connect_transport(int originx,int originy,int w,int h)78 connect_transport (int originx, int originy, int w, int h)
79 {
80 int x, y, mask, tflags;
81 short group, type;
82
83 static const short power_table[16] =
84 {
85 CST_POWERL_H_D, CST_POWERL_V_D, CST_POWERL_H_D, CST_POWERL_RD_D,
86 CST_POWERL_H_D, CST_POWERL_LD_D, CST_POWERL_H_D, CST_POWERL_LDR_D,
87 CST_POWERL_V_D, CST_POWERL_V_D, CST_POWERL_RU_D, CST_POWERL_UDR_D,
88 CST_POWERL_LU_D, CST_POWERL_LDU_D, CST_POWERL_LUR_D, CST_POWERL_LUDR_D
89 };
90 static const short track_table[16] =
91 {
92 CST_TRACK_LR, CST_TRACK_LR, CST_TRACK_UD, CST_TRACK_LU,
93 CST_TRACK_LR, CST_TRACK_LR, CST_TRACK_UR, CST_TRACK_LUR,
94 CST_TRACK_UD, CST_TRACK_LD, CST_TRACK_UD, CST_TRACK_LUD,
95 CST_TRACK_DR, CST_TRACK_LDR, CST_TRACK_UDR, CST_TRACK_LUDR
96 };
97 static const short road_table[16] =
98 {
99 CST_ROAD_LR, CST_ROAD_LR, CST_ROAD_UD, CST_ROAD_LU,
100 CST_ROAD_LR, CST_ROAD_LR, CST_ROAD_UR, CST_ROAD_LUR,
101 CST_ROAD_UD, CST_ROAD_LD, CST_ROAD_UD, CST_ROAD_LUD,
102 CST_ROAD_DR, CST_ROAD_LDR, CST_ROAD_UDR, CST_ROAD_LUDR
103 };
104 static const short rail_table[16] =
105 {
106 CST_RAIL_LR, CST_RAIL_LR, CST_RAIL_UD, CST_RAIL_LU,
107 CST_RAIL_LR, CST_RAIL_LR, CST_RAIL_UR, CST_RAIL_LUR,
108 CST_RAIL_UD, CST_RAIL_LD, CST_RAIL_UD, CST_RAIL_LUD,
109 CST_RAIL_DR, CST_RAIL_LDR, CST_RAIL_UDR, CST_RAIL_LUDR
110 };
111 static const short water_table[16] =
112 {
113 CST_WATER, CST_WATER_D, CST_WATER_R, CST_WATER_RD,
114 CST_WATER_L, CST_WATER_LD, CST_WATER_LR, CST_WATER_LRD,
115 CST_WATER_U, CST_WATER_UD, CST_WATER_UR, CST_WATER_URD,
116 CST_WATER_LU, CST_WATER_LUD, CST_WATER_LUR, CST_WATER_LURD
117 };
118
119 /* Adjust originx,originy,w,h to proper range */
120 if (originx <= 0) {
121 w -= 1 - originx;
122 originx = 1;
123 }
124 if (originy <= 0) {
125 h -= 1 - originy;
126 originy = 1;
127 }
128 if (originx + w >= WORLD_SIDE_LEN) {
129 w = WORLD_SIDE_LEN - originx;
130 }
131 if (originy + h >= WORLD_SIDE_LEN) {
132 h = WORLD_SIDE_LEN - originy;
133 }
134
135 for (x = originx; x < originx + w; x++) {
136 for (y = originy; y < originy + h; y++) {
137 switch (MP_GROUP(x,y))
138 {
139 case GROUP_POWER_LINE:
140 /* First, set up a mask indicating into which directions
141 power may be transferred */
142 mask = 0;
143 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
144 if (y > 0)
145 #endif
146 { /* up -- (ThMO) */
147 group = MP_GROUP(x,y-1);
148
149 /* see if dug under track, rail or road */
150
151 if (y > 1 && (group == GROUP_TRACK
152 || group == GROUP_RAIL
153 || group == GROUP_ROAD
154 || group == GROUP_WATER))
155 group = MP_GROUP(x,y-2);
156 switch (group)
157 {
158 case GROUP_POWER_LINE:
159 case GROUP_SOLAR_POWER:
160 case GROUP_SUBSTATION:
161 case GROUP_COAL_POWER:
162 mask |= 8;
163 break;
164 }
165 }
166 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
167 if (x > 0)
168 #endif
169 { /* left -- (ThMO) */
170 group = MP_GROUP(x-1,y);
171 if (x > 1 && (group == GROUP_TRACK
172 || group == GROUP_RAIL
173 || group == GROUP_ROAD
174 || group == GROUP_WATER))
175 group = MP_GROUP(x-2,y);
176 switch (group)
177 {
178 case GROUP_POWER_LINE:
179 case GROUP_SOLAR_POWER:
180 case GROUP_SUBSTATION:
181 case GROUP_COAL_POWER:
182 mask |= 4;
183 break;
184 }
185 }
186 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
187 if (x < WORLD_SIDE_LEN - 1)
188 #endif
189 { /* right -- (ThMO) */
190 group = MP_GROUP(x+1,y);
191 if (x < WORLD_SIDE_LEN - 2 && (group == GROUP_TRACK
192 || group == GROUP_RAIL
193 || group == GROUP_ROAD
194 || group == GROUP_WATER))
195 group = MP_GROUP(x+2,y);
196 switch (group)
197 {
198 case GROUP_WINDMILL:
199 if (MP_INFO(x + 1,y).int_2 < MODERN_WINDMILL_TECH)
200 break;
201 case GROUP_POWER_LINE:
202 case GROUP_SOLAR_POWER:
203 case GROUP_SUBSTATION:
204 case GROUP_COAL_POWER:
205 mask |= 2;
206 break;
207 }
208 }
209 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
210 if (y < WORLD_SIDE_LEN - 1)
211 #endif
212 { /* down -- (ThMO) */
213 group = MP_GROUP(x,y+1);
214 if (y < WORLD_SIDE_LEN - 2 && (group == GROUP_TRACK
215 || group == GROUP_RAIL
216 || group == GROUP_ROAD
217 || group == GROUP_WATER))
218 group = MP_GROUP(x,y+2);
219 switch (group)
220 {
221 case GROUP_WINDMILL:
222 if (MP_INFO(x,y + 1).int_2 < MODERN_WINDMILL_TECH)
223 break;
224 case GROUP_POWER_LINE:
225 case GROUP_SOLAR_POWER:
226 case GROUP_SUBSTATION:
227 case GROUP_COAL_POWER:
228 ++mask;
229 break;
230 }
231 }
232 /* Next, set the connectivity into MP_TYPE */
233 MP_TYPE(x,y) = power_table[mask];
234 /* Finally, adjust MP_TYPE to show electon bolt */
235 #ifdef commentout
236 WCK: This is done in do_power_line now
237 if (MP_INFO(x,y).int_1 != 0)
238 MP_TYPE(x,y) -= 11;
239 #endif
240 break;
241
242 case GROUP_TRACK:
243 #if FLAG_LEFT != 1 || FLAG_UP != 2 || FLAG_RIGHT != 4 || FLAG_DOWN != 8
244 #error check_track_graphics(): you loose
245 #error this algorithm depends on proper flag settings -- (ThMO)
246 #endif
247 mask = 0;
248 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
249 if (y > 0)
250 #endif
251 {
252 if (MP_GROUP(x,y-1) == GROUP_TRACK)
253 mask |= FLAG_UP;
254 }
255 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
256 if (x > 0)
257 #endif
258 {
259 if (MP_GROUP(x-1,y) == GROUP_TRACK)
260 mask |= FLAG_LEFT;
261 }
262 tflags = mask;
263 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
264 if (x < WORLD_SIDE_LEN - 1)
265 #endif
266 {
267 switch (MP_GROUP(x+1,y))
268 {
269 case GROUP_TRACK:
270 tflags |= FLAG_RIGHT;
271 case GROUP_COMMUNE:
272 case GROUP_COALMINE:
273 case GROUP_OREMINE:
274 case GROUP_INDUSTRY_L:
275 case GROUP_INDUSTRY_H:
276 case GROUP_RECYCLE:
277 case GROUP_TIP:
278 case GROUP_PORT:
279 mask |= FLAG_RIGHT;
280 break;
281 default:
282 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
283 if (y > 0)
284 #endif
285 if (MP_GROUP(x+1,y-1) == GROUP_COAL_POWER)
286 mask |= FLAG_RIGHT;
287 break;
288 }
289 }
290 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
291 if (y < WORLD_SIDE_LEN - 1)
292 #endif
293 {
294 switch (MP_GROUP(x,y+1))
295 {
296 case GROUP_TRACK:
297 tflags |= FLAG_DOWN;
298 case GROUP_COMMUNE:
299 case GROUP_COALMINE:
300 case GROUP_OREMINE:
301 case GROUP_INDUSTRY_L:
302 case GROUP_INDUSTRY_H:
303 case GROUP_RECYCLE:
304 case GROUP_TIP:
305 case GROUP_PORT:
306 mask |= FLAG_DOWN;
307 break;
308 default:
309 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
310 if (x > 0)
311 #endif
312 if (MP_GROUP(x-1,y+1) == GROUP_COAL_POWER)
313 mask |= FLAG_DOWN;
314 break;
315 }
316 }
317 MP_INFO(x,y).flags &= ~(FLAG_UP | FLAG_DOWN | FLAG_LEFT
318 | FLAG_RIGHT);
319 MP_INFO(x,y).flags |= tflags;
320 MP_TYPE(x,y) = track_table[mask];
321 break;
322
323 case GROUP_ROAD:
324 #if FLAG_LEFT != 1 || FLAG_UP != 2 || FLAG_RIGHT != 4 || FLAG_DOWN != 8
325 #error check_road_graphics(): you loose
326 #error this algorithm depends on proper flag settings -- (ThMO)
327 #endif
328 mask = 0;
329 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
330 if (y > 0)
331 #endif
332 {
333 if (MP_GROUP(x,y-1) == GROUP_ROAD)
334 mask |= FLAG_UP;
335 }
336 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
337 if (x > 0)
338 #endif
339 {
340 if (MP_GROUP(x-1,y) == GROUP_ROAD)
341 mask |= FLAG_LEFT;
342 }
343 tflags = mask;
344 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
345 if (x < WORLD_SIDE_LEN - 1)
346 #endif
347 {
348 switch (MP_GROUP(x+1,y))
349 {
350 case GROUP_ROAD:
351 tflags |= FLAG_RIGHT;
352 case GROUP_COMMUNE:
353 case GROUP_COALMINE:
354 case GROUP_OREMINE:
355 case GROUP_INDUSTRY_L:
356 case GROUP_INDUSTRY_H:
357 case GROUP_RECYCLE:
358 case GROUP_TIP:
359 case GROUP_PORT:
360 mask |= FLAG_RIGHT;
361 break;
362 default:
363 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
364 if (y > 0)
365 #endif
366 if (MP_GROUP(x+1,y-1) == GROUP_COAL_POWER)
367 mask |= FLAG_RIGHT;
368 break;
369 }
370 }
371 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
372 if (y < WORLD_SIDE_LEN - 1)
373 #endif
374 {
375 switch (MP_GROUP(x,y+1))
376 {
377 case GROUP_ROAD:
378 tflags |= FLAG_DOWN;
379 case GROUP_COMMUNE:
380 case GROUP_COALMINE:
381 case GROUP_OREMINE:
382 case GROUP_INDUSTRY_L:
383 case GROUP_INDUSTRY_H:
384 case GROUP_RECYCLE:
385 case GROUP_TIP:
386 case GROUP_PORT:
387 mask |= FLAG_DOWN;
388 break;
389 default:
390 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
391 if (x > 0)
392 #endif
393 if (MP_GROUP(x-1,y+1) == GROUP_COAL_POWER)
394 mask |= FLAG_DOWN;
395 break;
396 }
397 }
398 MP_INFO(x,y).flags &= ~(FLAG_UP | FLAG_DOWN | FLAG_LEFT
399 | FLAG_RIGHT);
400 MP_INFO(x,y).flags |= tflags;
401 MP_TYPE(x,y) = road_table[mask];
402 break;
403
404 case GROUP_RAIL:
405 #if FLAG_LEFT != 1 || FLAG_UP != 2 || FLAG_RIGHT != 4 || FLAG_DOWN != 8
406 #error check_rail_graphics(): you loose
407 #error this algorithm depends on proper flag settings -- (ThMO)
408 #endif
409 mask = 0;
410 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
411 if (y > 0)
412 #endif
413 {
414 if (MP_GROUP(x,y-1) == GROUP_RAIL)
415 mask |= FLAG_UP;
416 }
417 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
418 if (x > 0)
419 #endif
420 {
421 if (MP_GROUP(x-1,y) == GROUP_RAIL)
422 mask |= FLAG_LEFT;
423 }
424 tflags = mask;
425 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
426 if (x < WORLD_SIDE_LEN - 1)
427 #endif
428 {
429 switch (MP_GROUP(x+1,y))
430 {
431 case GROUP_RAIL:
432 tflags |= FLAG_RIGHT;
433 case GROUP_COMMUNE:
434 case GROUP_COALMINE:
435 case GROUP_OREMINE:
436 case GROUP_INDUSTRY_L:
437 case GROUP_INDUSTRY_H:
438 case GROUP_RECYCLE:
439 case GROUP_TIP:
440 case GROUP_PORT:
441 mask |= FLAG_RIGHT;
442 break;
443 default:
444 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
445 if (y > 0)
446 #endif
447 if (MP_GROUP(x+1,y-1) == GROUP_COAL_POWER)
448 mask |= FLAG_RIGHT;
449 break;
450 }
451 }
452 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
453 if (y < WORLD_SIDE_LEN - 1)
454 #endif
455 {
456 switch (MP_GROUP(x,y + 1))
457 {
458 case GROUP_RAIL:
459 tflags |= FLAG_DOWN;
460 case GROUP_COMMUNE:
461 case GROUP_COALMINE:
462 case GROUP_OREMINE:
463 case GROUP_INDUSTRY_L:
464 case GROUP_INDUSTRY_H:
465 case GROUP_RECYCLE:
466 case GROUP_TIP:
467 case GROUP_PORT:
468 mask |= FLAG_DOWN;
469 break;
470 default:
471 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
472 if (x > 0)
473 #endif
474 if (MP_GROUP(x - 1,y + 1)
475 == GROUP_COAL_POWER)
476 mask |= FLAG_DOWN;
477 break;
478 }
479 }
480 MP_INFO(x,y).flags &= ~(FLAG_UP | FLAG_DOWN | FLAG_LEFT
481 | FLAG_RIGHT);
482 MP_INFO(x,y).flags |= tflags;
483 MP_TYPE(x,y) = rail_table[mask];
484 break;
485
486 case GROUP_WATER:
487 mask = 0;
488 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
489 if (y > 0)
490 #endif
491 { /* up -- (ThMO) */
492 if (MP_GROUP(x,y - 1)
493 == GROUP_WATER)
494 mask |= 8;
495 }
496 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
497 if (x > 0)
498 #endif
499 { /* left -- (ThMO) */
500 type = MP_TYPE(x - 1,y);
501 if ((type == CST_USED &&
502 MP_GROUP(MP_INFO(x-1,y).int_1,MP_INFO(x-1,y).int_2)
503 == GROUP_PORT)
504 || get_group_of_type(type) == GROUP_WATER)
505 mask |= 4;
506 }
507 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
508 if (x < WORLD_SIDE_LEN - 1)
509 #endif
510 { /* right -- (ThMO) */
511 if (MP_GROUP(x + 1,y)
512 == GROUP_WATER)
513 mask |= 2;
514 }
515 #ifdef THOMMY_MAY_BE_WRONG /* just in case -- (ThMO) */
516 if (y < WORLD_SIDE_LEN - 1)
517 #endif
518 { /* down -- (ThMO) */
519 if (MP_GROUP(x,y + 1)
520 == GROUP_WATER)
521 ++mask;
522 }
523 MP_TYPE(x,y) = water_table[mask];
524 break;
525 } /* end switch */
526 } /* end for */
527 } /* end for */
528 }
529
530