]> 4ch.mooo.com Git - 16.git/blob - 16/roads/INITROAD.C
refresh wwww
[16.git] / 16 / roads / INITROAD.C
1 #define INITROAD_C\r
2 \r
3 #include <stdlib.h>\r
4 #include <time.h>\r
5 #include <fastgraf.h>\r
6 #include "roads.h"\r
7 #include "tiles.h"\r
8 \r
9 extern int far *topography;      /* BACKGROUND TILE LIST (ARRAY) */\r
10 extern int far *terrain;      /* FOREGROUND TILE LIST (ARRAY) */\r
11 \r
12 /* FOR AI - NUMBER OF ROADS TO PLACE ON SCREEN */\r
13 #define MAX_ROADS ((WORLD_WIDTH+WORLD_HEIGHT)/2)\r
14 #define MIN_ROADS ((WORLD_WIDTH+WORLD_HEIGHT)/8)\r
15 #define CHANCE_CROSSROAD 75 /* 3/4 CHANCE OF A CROSSROAD VS T */\r
16 \r
17 /* DIRECTIONS */\r
18 #define NUM_DIRECTIONS  4\r
19 #define FIRST_DIRECTION 1\r
20 \r
21 #define DIRECTION_UP    1\r
22 #define DIRECTION_DOWN  2\r
23 #define DIRECTION_LEFT  3\r
24 #define DIRECTION_RIGHT 4\r
25 \r
26 #define ROAD_LEADERS 12 /* USED IN CREATE_ROADS */\r
27 \r
28 /*\r
29  *\r
30  * Randomly creates roads and places them in the foreground tile list.\r
31  * This function overwrites other non-road foreground tiles.\r
32  * (To prevent this, call this function first.)\r
33  *\r
34  */\r
35 void create_roads (void)\r
36 {\r
37     int entry, keepgoing=TRUE, direction, chance;\r
38     int x,y,nextx,nexty; /* LOCATION OF CURRENTLY PLACED ROAD TILE */\r
39     int roads_left; /* NUMBER OF COMPLETE ROADS LEFT TO PLACE */\r
40     int failed_roads=0;\r
41     int current_tile;\r
42 \r
43                 /* ROADS ARE PICKED FROM THESE LISTS -- INCREASE ROAD_LEADERS  */\r
44         /* AND ADD ROAD TILES TO THESE LISTS TO INCREASE CHANCE OF     */\r
45         /* SPECIFIED ROADS BEING PLACED                                */\r
46     int roads_to_right [ROAD_LEADERS] = { ROAD_H, ROAD_H, ROAD_UR, ROAD_DR,\r
47                                           ROAD_H, ROAD_H, ROAD_H, ROAD_H,\r
48                                           ROAD_H, ROAD_H, ROAD_H, ROAD_H,  };\r
49     int roads_to_left  [ROAD_LEADERS] = { ROAD_H, ROAD_H, ROAD_UL, ROAD_DL,\r
50                                           ROAD_H, ROAD_H, ROAD_H, ROAD_H,\r
51                                           ROAD_H, ROAD_H, ROAD_H, ROAD_H,  };\r
52     int roads_to_down  [ROAD_LEADERS] = { ROAD_V, ROAD_V, ROAD_UL, ROAD_UR,\r
53                                           ROAD_V, ROAD_V, ROAD_V, ROAD_V,\r
54                                           ROAD_V, ROAD_V, ROAD_V, ROAD_V,  };\r
55     int roads_to_up    [ROAD_LEADERS] = { ROAD_V, ROAD_V, ROAD_DL, ROAD_DR,\r
56                                                                                   ROAD_V, ROAD_V, ROAD_V, ROAD_V,\r
57                                           ROAD_V, ROAD_V, ROAD_V, ROAD_V,  };\r
58 \r
59     roads_left=random (MAX_ROADS-MIN_ROADS)+MIN_ROADS;\r
60 \r
61         /************************************************\\r
62          *     PLACE FIRST TILE AT WORLD SCREEN EDGE    *\r
63         \************************************************/\r
64 \r
65     while (roads_left-- && failed_roads<=MAX_FAILS)\r
66     {\r
67             /* PICK RANDOM ENTRY POINT */\r
68         keepgoing=TRUE;\r
69         entry=random(NUM_DIRECTIONS)+FIRST_DIRECTION;\r
70         switch (entry)\r
71         {\r
72 /********/  case DIRECTION_UP: /* TOP ENTRY */\r
73 \r
74             x=random(WORLD_WIDTH); y=0;\r
75             current_tile=terrain[WORLD_TILE(x,y)];\r
76 \r
77             if (!isroad(current_tile))\r
78             {\r
79                 current_tile=terrain[WORLD_TILE(x,y)]=\r
80                     roads_to_up[random(ROAD_LEADERS)];\r
81                 direction=roadexit(current_tile, DIRECTION_DOWN);\r
82                                 break;\r
83             }\r
84 \r
85             else\r
86             {\r
87                 roads_left++;\r
88                 failed_roads++;\r
89                 keepgoing=FALSE;\r
90                 break;\r
91             }\r
92 \r
93 /********/  case DIRECTION_DOWN: /* BOTTOM ENTRY */\r
94 \r
95                         x=random(WORLD_WIDTH); y=WORLD_HEIGHT-1;\r
96             current_tile=terrain[WORLD_TILE(x,y)];\r
97 \r
98             if (!isroad(current_tile))\r
99             {\r
100                 current_tile=terrain[WORLD_TILE(x,y)]=\r
101                     roads_to_down[random(ROAD_LEADERS)];\r
102                 direction=roadexit(current_tile, DIRECTION_UP);\r
103             }\r
104 \r
105             else\r
106             {\r
107                 roads_left++;\r
108                                 failed_roads++;\r
109                 keepgoing=FALSE;\r
110             }\r
111             break;\r
112 \r
113 /********/  case DIRECTION_LEFT: /* LEFT ENTRY */\r
114 \r
115             x=0; y=random(WORLD_HEIGHT);\r
116             current_tile=terrain[WORLD_TILE(x,y)];\r
117 \r
118             if (!isroad(current_tile))\r
119             {\r
120                 current_tile=terrain[WORLD_TILE(x,y)]=\r
121                                         roads_to_left[random(ROAD_LEADERS)];\r
122                 direction=roadexit(current_tile, DIRECTION_RIGHT);\r
123             }\r
124 \r
125             else\r
126             {\r
127                 roads_left++;\r
128                 failed_roads++;\r
129                 keepgoing=FALSE;\r
130             }\r
131             break;\r
132 \r
133 /********/  case DIRECTION_RIGHT: /* RIGHT ENTRY */\r
134 \r
135             x=WORLD_WIDTH-1; y=random(WORLD_HEIGHT);\r
136             current_tile=terrain[WORLD_TILE(x,y)];\r
137 \r
138             if (!isroad(current_tile))\r
139             {\r
140                 current_tile=terrain[WORLD_TILE(x,y)]=\r
141                     roads_to_right[random(ROAD_LEADERS)];\r
142                 direction=roadexit(current_tile, DIRECTION_LEFT);\r
143             }\r
144 \r
145             else\r
146             {\r
147                                 roads_left++;\r
148                 failed_roads++;\r
149                 keepgoing=FALSE;\r
150             }\r
151             break;\r
152         }\r
153 \r
154         /************************************************\\r
155          * PLACE SUBSEQUENT TILES AWAY FROM ENTRY POINT *\r
156         \************************************************/\r
157 \r
158         while (keepgoing)\r
159         {\r
160                         switch (direction)\r
161             {\r
162 /********/      case DIRECTION_UP: /* UP */\r
163 \r
164                 if (--y<0)\r
165                 {\r
166                     keepgoing=FALSE;\r
167                     break;\r
168                 }\r
169 \r
170                 current_tile=terrain[WORLD_TILE(x,y)];\r
171                 if (!isroad(current_tile))\r
172                 {\r
173                     current_tile=terrain[WORLD_TILE(x,y)]=\r
174                         roads_to_down[random(ROAD_LEADERS)];\r
175                     direction=roadexit(current_tile, DIRECTION_UP);\r
176                 }\r
177 \r
178                 else /* INTERSECTION OCCURS */\r
179                 {\r
180                     if (random(100)>=CHANCE_CROSSROAD &&\r
181                         terrain[WORLD_TILE(x,y-1)]==EMPTY_TILE)\r
182                     {\r
183                         keepgoing=FALSE;\r
184                         terrain[WORLD_TILE(x,y)]=makeintersection\r
185                             (current_tile, DIRECTION_DOWN);\r
186                                         }\r
187 \r
188                     else /* CROSSROAD AND CONTINUE */\r
189                     {\r
190                         terrain[WORLD_TILE(x,y)]=makeintersection\r
191                             (makeintersection(current_tile, DIRECTION_UP),\r
192                             DIRECTION_DOWN); /* ADD BOTH RAMPS */\r
193                     }\r
194                 }\r
195                 break;\r
196 \r
197 /********/      case DIRECTION_DOWN:  /* DOWN */\r
198 \r
199                                 if (++y>=WORLD_HEIGHT)\r
200                 {\r
201                     keepgoing=FALSE;\r
202                     break;\r
203                 }\r
204 \r
205                 current_tile=terrain[WORLD_TILE(x,y)];\r
206                 if (!isroad(current_tile))\r
207                 {\r
208                     current_tile=terrain[WORLD_TILE(x,y)]=\r
209                         roads_to_up[random(ROAD_LEADERS)];\r
210                     direction=roadexit(current_tile, DIRECTION_DOWN);\r
211                 }\r
212 \r
213                 else /* INTERSECTION OCCURS */\r
214                 {\r
215                     if (random(100)>=CHANCE_CROSSROAD &&\r
216                         terrain[WORLD_TILE(x,y+1)]==EMPTY_TILE)\r
217 \r
218                     {\r
219                         keepgoing=FALSE;\r
220                         terrain[WORLD_TILE(x,y)]=makeintersection\r
221                             (current_tile, DIRECTION_UP);\r
222                     }\r
223 \r
224                     else /* CROSSROAD AND CONTINUE */\r
225                                         {\r
226                         terrain[WORLD_TILE(x,y)]=makeintersection\r
227                             (makeintersection(current_tile, DIRECTION_DOWN),\r
228                             DIRECTION_UP); /* ADD BOTH RAMPS */\r
229                     }\r
230                 }\r
231                 break;\r
232 \r
233 /********/      case DIRECTION_LEFT: /* LEFT */\r
234 \r
235                 if (--x<0)\r
236                 {\r
237                     keepgoing=FALSE;\r
238                                         break;\r
239                 }\r
240 \r
241                 current_tile=terrain[WORLD_TILE(x,y)];\r
242                 if (!isroad(current_tile))\r
243                 {\r
244                     current_tile=terrain[WORLD_TILE(x,y)]=\r
245                         roads_to_right[random(ROAD_LEADERS)];\r
246                     direction=roadexit(current_tile, DIRECTION_LEFT);\r
247                 }\r
248 \r
249                 else /* INTERSECTION OCCURS */\r
250                 {\r
251                                         if (random(100)>=CHANCE_CROSSROAD &&\r
252                         terrain[WORLD_TILE(x-1,y)]==EMPTY_TILE)\r
253 \r
254                     {\r
255                         keepgoing=FALSE;\r
256                         terrain[WORLD_TILE(x,y)]=makeintersection\r
257                             (current_tile, DIRECTION_RIGHT);\r
258                     }\r
259 \r
260                     else /* CROSSROAD AND CONTINUE */\r
261                     {\r
262                         terrain[WORLD_TILE(x,y)]=makeintersection\r
263                             (makeintersection(current_tile, DIRECTION_LEFT),\r
264                                                         DIRECTION_RIGHT); /* ADD BOTH RAMPS */\r
265                     }\r
266                 }\r
267                 break;\r
268 \r
269 /********/      case DIRECTION_RIGHT: /* RIGHT */\r
270 \r
271                 if (++x>=WORLD_WIDTH)\r
272                 {\r
273                     keepgoing=FALSE;\r
274                     break;\r
275                 }\r
276 \r
277                 current_tile=terrain[WORLD_TILE(x,y)];\r
278                 if (!isroad(current_tile))\r
279                 {\r
280                     current_tile=terrain[WORLD_TILE(x,y)]=\r
281                         roads_to_left[random(ROAD_LEADERS)];\r
282                     direction=roadexit(current_tile, DIRECTION_RIGHT);\r
283                 }\r
284 \r
285                 else /* INTERSECTION OCCURS */\r
286                 {\r
287                     if (random(100)>=CHANCE_CROSSROAD &&\r
288                         terrain[WORLD_TILE(x+1,y)]==EMPTY_TILE)\r
289 \r
290                                         {\r
291                         keepgoing=FALSE;\r
292                         terrain[WORLD_TILE(x,y)]=makeintersection\r
293                             (current_tile, DIRECTION_LEFT);\r
294                     }\r
295 \r
296                     else /* CROSSROAD AND CONTINUE */\r
297                     {\r
298                         terrain[WORLD_TILE(x,y)]=makeintersection\r
299                             (makeintersection(current_tile, DIRECTION_RIGHT),\r
300                             DIRECTION_LEFT); /* ADD BOTH RAMPS */\r
301                     }\r
302                 }\r
303                                 break;\r
304             } /* "DIRECTION" HERE */\r
305         } /* STOP "KEEPGOING" HERE */\r
306     }\r
307 }\r
308 \r
309 /*\r
310  *\r
311  * Returns the unspecified direction in an angled road.\r
312  *\r
313  */\r
314 int roadexit (int road, int direction)\r
315 {\r
316         switch (direction)\r
317     {\r
318         case DIRECTION_UP: /* up */\r
319         if (road==ROAD_V)  return DIRECTION_UP;\r
320         if (road==ROAD_UL) return DIRECTION_LEFT;\r
321         if (road==ROAD_UR) return DIRECTION_RIGHT;\r
322         break;\r
323 \r
324         case DIRECTION_DOWN: /* down */\r
325         if (road==ROAD_V)  return DIRECTION_DOWN;\r
326         if (road==ROAD_DL) return DIRECTION_LEFT;\r
327         if (road==ROAD_DR) return DIRECTION_RIGHT;\r
328         break;\r
329 \r
330         case DIRECTION_LEFT: /* left */\r
331         if (road==ROAD_DR) return DIRECTION_UP;\r
332         if (road==ROAD_UR) return DIRECTION_DOWN;\r
333         if (road==ROAD_H)  return DIRECTION_LEFT;\r
334         break;\r
335 \r
336         case DIRECTION_RIGHT: /* right */\r
337         if (road==ROAD_DL) return DIRECTION_UP;\r
338         if (road==ROAD_UL) return DIRECTION_DOWN;\r
339         if (road==ROAD_H)  return DIRECTION_RIGHT;\r
340         break;\r
341     }\r
342 \r
343     fg_music ("A$");\r
344     return ERROR_TILE;\r
345 }\r
346 \r
347 /*\r
348  *\r
349  * Adds a road (ramp) to the specified road, and returns the\r
350  * tile number of what the new road is made of.\r
351  *\r
352  */\r
353 int makeintersection (int road, int ramp)\r
354 {\r
355         switch (road)\r
356     {\r
357         case ROAD_X:  /* Å */\r
358         return ROAD_X;\r
359 \r
360         case ROAD_V:  /* ³ */\r
361         if (ramp==DIRECTION_LEFT) return ROAD_TL;\r
362         if (ramp==DIRECTION_RIGHT) return ROAD_TR;\r
363         return ROAD_V;\r
364 \r
365         case ROAD_H:  /* Ä */\r
366         if (ramp==DIRECTION_UP) return ROAD_TU;\r
367         if (ramp==DIRECTION_DOWN) return ROAD_TD;\r
368                 return ROAD_H;\r
369 \r
370         case ROAD_UR: /* Ú */\r
371         if (ramp==DIRECTION_UP) return ROAD_TR;\r
372         if (ramp==DIRECTION_LEFT) return ROAD_TD;\r
373         return ROAD_UR;\r
374 \r
375         case ROAD_UL: /* ¿ */\r
376         if (ramp==DIRECTION_UP) return ROAD_TL;\r
377         if (ramp==DIRECTION_RIGHT) return ROAD_TD;\r
378         return ROAD_UL;\r
379 \r
380         case ROAD_DR: /* À */\r
381                 if (ramp==DIRECTION_DOWN) return ROAD_TR;\r
382         if (ramp==DIRECTION_LEFT) return ROAD_TU;\r
383         return ROAD_DR;\r
384 \r
385         case ROAD_DL: /* Ù */\r
386         if (ramp==DIRECTION_DOWN) return ROAD_TL;\r
387         if (ramp==DIRECTION_RIGHT) return ROAD_TU;\r
388         return ROAD_DL;\r
389 \r
390         case ROAD_TL: /* ´ */\r
391         if (ramp==DIRECTION_RIGHT) return ROAD_X;\r
392         return ROAD_TL;\r
393 \r
394                 case ROAD_TR: /* Ã */\r
395         if (ramp==DIRECTION_LEFT) return ROAD_X;\r
396         return ROAD_TR;\r
397 \r
398         case ROAD_TU: /* Á */\r
399         if (ramp==DIRECTION_DOWN) return ROAD_X;\r
400         return ROAD_TU;\r
401 \r
402         case ROAD_TD: /* Â */\r
403         if (ramp==DIRECTION_UP) return ROAD_X;\r
404         return ROAD_TD;\r
405     }\r
406 \r
407         fg_music ("A$");\r
408     return ERROR_TILE;\r
409 }\r
410 \r
411 /*\r
412     AI USED IN ROAD FUNCTIONS:\r
413     pick random entry point on one of the four sides\r
414     place subsequent tiles with tendency to move from screen\r
415     place subsequent tiles with tendency use V or H pieces if just used\r
416     if hit existing tile, either\r
417     a) cross over road and continue, using X tile\r
418     b) terminate road with a T\r
419     repeat until MAX_ROADS complete\r
420 */\r
421 \r
422 /*\r
423  *\r
424  * Adds edges to places where grass and dirt meet.\r
425  * Called by init_background() to liven up background display.\r
426  *\r
427  */\r
428 void add_dirt_edges (void)\r
429 {\r
430     register int x, y;\r
431     int tile;\r
432 \r
433     /* ADD 90 DEGREE EDGES */\r
434     for (y=0; y<WORLD_HEIGHT; y++)\r
435     for (x=0; x<WORLD_WIDTH; x++)\r
436     if (isdirt(topography[WORLD_TILE(x,y)]))\r
437     {\r
438         tile=0; /* ADD UP BINARY TILE NUMBER */\r
439         if (y-1>=0) tile+=isgrass(topography[WORLD_TILE(x,y-1)]);\r
440         if (x+1<WORLD_WIDTH) tile+=isgrass(topography[WORLD_TILE(x+1,y)])*2;\r
441         if (y+1<WORLD_HEIGHT) tile+=isgrass(topography[WORLD_TILE(x,y+1)])*4;\r
442         if (x-1>=0) tile+=isgrass(topography[WORLD_TILE(x-1,y)])*8;\r
443 \r
444         /* CONVERT BINARY TILE NUMBER TO ACTUAL */\r
445         switch (tile)\r
446         {\r
447             case 1:  tile=DIRTEDGE_U;    break;\r
448             case 2:  tile=DIRTEDGE_R;    break;\r
449             case 3:  tile=DIRTEDGE_UR;   break;\r
450             case 4:  tile=DIRTEDGE_D;    break;\r
451             case 5:  tile=DIRTEDGE_UD;   break;\r
452             case 6:  tile=DIRTEDGE_RD;   break;\r
453             case 7:  tile=DIRTEDGE_URD;  break;\r
454             case 8:  tile=DIRTEDGE_L;    break;\r
455             case 9:  tile=DIRTEDGE_UL;   break;\r
456             case 10: tile=DIRTEDGE_RL;   break;\r
457             case 11: tile=DIRTEDGE_URL;  break;\r
458             case 12: tile=DIRTEDGE_DL;   break;\r
459             case 13: tile=DIRTEDGE_UDL;  break;\r
460             case 14: tile=DIRTEDGE_RDL;  break;\r
461             case 15: tile=DIRTEDGE_URDL; break;\r
462             case 0:  tile=topography[WORLD_TILE(x,y)]; break; /* NO CHANGE */\r
463         }\r
464         topography[WORLD_TILE(x,y)]=tile; /* CHANGE TILE */\r
465     }\r
466 }\r
467 \r