5 #include <fastgraf.h>
\r
9 extern int far *topography; /* BACKGROUND TILE LIST (ARRAY) */
\r
10 extern int far *terrain; /* FOREGROUND TILE LIST (ARRAY) */
\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
18 #define NUM_DIRECTIONS 4
\r
19 #define FIRST_DIRECTION 1
\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
26 #define ROAD_LEADERS 12 /* USED IN CREATE_ROADS */
\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
35 void create_roads (void)
\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
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
59 roads_left=random (MAX_ROADS-MIN_ROADS)+MIN_ROADS;
\r
61 /************************************************\
\r
62 * PLACE FIRST TILE AT WORLD SCREEN EDGE *
\r
63 \************************************************/
\r
65 while (roads_left-- && failed_roads<=MAX_FAILS)
\r
67 /* PICK RANDOM ENTRY POINT */
\r
69 entry=random(NUM_DIRECTIONS)+FIRST_DIRECTION;
\r
72 /********/ case DIRECTION_UP: /* TOP ENTRY */
\r
74 x=random(WORLD_WIDTH); y=0;
\r
75 current_tile=terrain[WORLD_TILE(x,y)];
\r
77 if (!isroad(current_tile))
\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
93 /********/ case DIRECTION_DOWN: /* BOTTOM ENTRY */
\r
95 x=random(WORLD_WIDTH); y=WORLD_HEIGHT-1;
\r
96 current_tile=terrain[WORLD_TILE(x,y)];
\r
98 if (!isroad(current_tile))
\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
113 /********/ case DIRECTION_LEFT: /* LEFT ENTRY */
\r
115 x=0; y=random(WORLD_HEIGHT);
\r
116 current_tile=terrain[WORLD_TILE(x,y)];
\r
118 if (!isroad(current_tile))
\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
133 /********/ case DIRECTION_RIGHT: /* RIGHT ENTRY */
\r
135 x=WORLD_WIDTH-1; y=random(WORLD_HEIGHT);
\r
136 current_tile=terrain[WORLD_TILE(x,y)];
\r
138 if (!isroad(current_tile))
\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
154 /************************************************\
\r
155 * PLACE SUBSEQUENT TILES AWAY FROM ENTRY POINT *
\r
156 \************************************************/
\r
162 /********/ case DIRECTION_UP: /* UP */
\r
170 current_tile=terrain[WORLD_TILE(x,y)];
\r
171 if (!isroad(current_tile))
\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
178 else /* INTERSECTION OCCURS */
\r
180 if (random(100)>=CHANCE_CROSSROAD &&
\r
181 terrain[WORLD_TILE(x,y-1)]==EMPTY_TILE)
\r
184 terrain[WORLD_TILE(x,y)]=makeintersection
\r
185 (current_tile, DIRECTION_DOWN);
\r
188 else /* CROSSROAD AND CONTINUE */
\r
190 terrain[WORLD_TILE(x,y)]=makeintersection
\r
191 (makeintersection(current_tile, DIRECTION_UP),
\r
192 DIRECTION_DOWN); /* ADD BOTH RAMPS */
\r
197 /********/ case DIRECTION_DOWN: /* DOWN */
\r
199 if (++y>=WORLD_HEIGHT)
\r
205 current_tile=terrain[WORLD_TILE(x,y)];
\r
206 if (!isroad(current_tile))
\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
213 else /* INTERSECTION OCCURS */
\r
215 if (random(100)>=CHANCE_CROSSROAD &&
\r
216 terrain[WORLD_TILE(x,y+1)]==EMPTY_TILE)
\r
220 terrain[WORLD_TILE(x,y)]=makeintersection
\r
221 (current_tile, DIRECTION_UP);
\r
224 else /* CROSSROAD AND CONTINUE */
\r
226 terrain[WORLD_TILE(x,y)]=makeintersection
\r
227 (makeintersection(current_tile, DIRECTION_DOWN),
\r
228 DIRECTION_UP); /* ADD BOTH RAMPS */
\r
233 /********/ case DIRECTION_LEFT: /* LEFT */
\r
241 current_tile=terrain[WORLD_TILE(x,y)];
\r
242 if (!isroad(current_tile))
\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
249 else /* INTERSECTION OCCURS */
\r
251 if (random(100)>=CHANCE_CROSSROAD &&
\r
252 terrain[WORLD_TILE(x-1,y)]==EMPTY_TILE)
\r
256 terrain[WORLD_TILE(x,y)]=makeintersection
\r
257 (current_tile, DIRECTION_RIGHT);
\r
260 else /* CROSSROAD AND CONTINUE */
\r
262 terrain[WORLD_TILE(x,y)]=makeintersection
\r
263 (makeintersection(current_tile, DIRECTION_LEFT),
\r
264 DIRECTION_RIGHT); /* ADD BOTH RAMPS */
\r
269 /********/ case DIRECTION_RIGHT: /* RIGHT */
\r
271 if (++x>=WORLD_WIDTH)
\r
277 current_tile=terrain[WORLD_TILE(x,y)];
\r
278 if (!isroad(current_tile))
\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
285 else /* INTERSECTION OCCURS */
\r
287 if (random(100)>=CHANCE_CROSSROAD &&
\r
288 terrain[WORLD_TILE(x+1,y)]==EMPTY_TILE)
\r
292 terrain[WORLD_TILE(x,y)]=makeintersection
\r
293 (current_tile, DIRECTION_LEFT);
\r
296 else /* CROSSROAD AND CONTINUE */
\r
298 terrain[WORLD_TILE(x,y)]=makeintersection
\r
299 (makeintersection(current_tile, DIRECTION_RIGHT),
\r
300 DIRECTION_LEFT); /* ADD BOTH RAMPS */
\r
304 } /* "DIRECTION" HERE */
\r
305 } /* STOP "KEEPGOING" HERE */
\r
311 * Returns the unspecified direction in an angled road.
\r
314 int roadexit (int road, int direction)
\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
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
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
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
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
353 int makeintersection (int road, int ramp)
\r
357 case ROAD_X: /* Å */
\r
360 case ROAD_V: /* ³ */
\r
361 if (ramp==DIRECTION_LEFT) return ROAD_TL;
\r
362 if (ramp==DIRECTION_RIGHT) return ROAD_TR;
\r
365 case ROAD_H: /* Ä */
\r
366 if (ramp==DIRECTION_UP) return ROAD_TU;
\r
367 if (ramp==DIRECTION_DOWN) return ROAD_TD;
\r
370 case ROAD_UR: /* Ú */
\r
371 if (ramp==DIRECTION_UP) return ROAD_TR;
\r
372 if (ramp==DIRECTION_LEFT) return ROAD_TD;
\r
375 case ROAD_UL: /* ¿ */
\r
376 if (ramp==DIRECTION_UP) return ROAD_TL;
\r
377 if (ramp==DIRECTION_RIGHT) return ROAD_TD;
\r
380 case ROAD_DR: /* À */
\r
381 if (ramp==DIRECTION_DOWN) return ROAD_TR;
\r
382 if (ramp==DIRECTION_LEFT) return ROAD_TU;
\r
385 case ROAD_DL: /* Ù */
\r
386 if (ramp==DIRECTION_DOWN) return ROAD_TL;
\r
387 if (ramp==DIRECTION_RIGHT) return ROAD_TU;
\r
390 case ROAD_TL: /* ´ */
\r
391 if (ramp==DIRECTION_RIGHT) return ROAD_X;
\r
394 case ROAD_TR: /* Ã */
\r
395 if (ramp==DIRECTION_LEFT) return ROAD_X;
\r
398 case ROAD_TU: /* Á */
\r
399 if (ramp==DIRECTION_DOWN) return ROAD_X;
\r
402 case ROAD_TD: /* Â */
\r
403 if (ramp==DIRECTION_UP) return ROAD_X;
\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
424 * Adds edges to places where grass and dirt meet.
\r
425 * Called by init_background() to liven up background display.
\r
428 void add_dirt_edges (void)
\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
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
444 /* CONVERT BINARY TILE NUMBER TO ACTUAL */
\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
464 topography[WORLD_TILE(x,y)]=tile; /* CHANGE TILE */
\r