]> 4ch.mooo.com Git - 16.git/blobdiff - 16/roads/INITROAD.C
refresh wwww
[16.git] / 16 / roads / INITROAD.C
diff --git a/16/roads/INITROAD.C b/16/roads/INITROAD.C
new file mode 100755 (executable)
index 0000000..c83effe
--- /dev/null
@@ -0,0 +1,467 @@
+#define INITROAD_C\r
+\r
+#include <stdlib.h>\r
+#include <time.h>\r
+#include <fastgraf.h>\r
+#include "roads.h"\r
+#include "tiles.h"\r
+\r
+extern int far *topography;      /* BACKGROUND TILE LIST (ARRAY) */\r
+extern int far *terrain;      /* FOREGROUND TILE LIST (ARRAY) */\r
+\r
+/* FOR AI - NUMBER OF ROADS TO PLACE ON SCREEN */\r
+#define MAX_ROADS ((WORLD_WIDTH+WORLD_HEIGHT)/2)\r
+#define MIN_ROADS ((WORLD_WIDTH+WORLD_HEIGHT)/8)\r
+#define CHANCE_CROSSROAD 75 /* 3/4 CHANCE OF A CROSSROAD VS T */\r
+\r
+/* DIRECTIONS */\r
+#define NUM_DIRECTIONS  4\r
+#define FIRST_DIRECTION 1\r
+\r
+#define DIRECTION_UP    1\r
+#define DIRECTION_DOWN  2\r
+#define DIRECTION_LEFT  3\r
+#define DIRECTION_RIGHT 4\r
+\r
+#define ROAD_LEADERS 12 /* USED IN CREATE_ROADS */\r
+\r
+/*\r
+ *\r
+ * Randomly creates roads and places them in the foreground tile list.\r
+ * This function overwrites other non-road foreground tiles.\r
+ * (To prevent this, call this function first.)\r
+ *\r
+ */\r
+void create_roads (void)\r
+{\r
+    int entry, keepgoing=TRUE, direction, chance;\r
+    int x,y,nextx,nexty; /* LOCATION OF CURRENTLY PLACED ROAD TILE */\r
+    int roads_left; /* NUMBER OF COMPLETE ROADS LEFT TO PLACE */\r
+    int failed_roads=0;\r
+    int current_tile;\r
+\r
+               /* ROADS ARE PICKED FROM THESE LISTS -- INCREASE ROAD_LEADERS  */\r
+        /* AND ADD ROAD TILES TO THESE LISTS TO INCREASE CHANCE OF     */\r
+        /* SPECIFIED ROADS BEING PLACED                                */\r
+    int roads_to_right [ROAD_LEADERS] = { ROAD_H, ROAD_H, ROAD_UR, ROAD_DR,\r
+                                          ROAD_H, ROAD_H, ROAD_H, ROAD_H,\r
+                                          ROAD_H, ROAD_H, ROAD_H, ROAD_H,  };\r
+    int roads_to_left  [ROAD_LEADERS] = { ROAD_H, ROAD_H, ROAD_UL, ROAD_DL,\r
+                                          ROAD_H, ROAD_H, ROAD_H, ROAD_H,\r
+                                          ROAD_H, ROAD_H, ROAD_H, ROAD_H,  };\r
+    int roads_to_down  [ROAD_LEADERS] = { ROAD_V, ROAD_V, ROAD_UL, ROAD_UR,\r
+                                          ROAD_V, ROAD_V, ROAD_V, ROAD_V,\r
+                                          ROAD_V, ROAD_V, ROAD_V, ROAD_V,  };\r
+    int roads_to_up    [ROAD_LEADERS] = { ROAD_V, ROAD_V, ROAD_DL, ROAD_DR,\r
+                                                                                 ROAD_V, ROAD_V, ROAD_V, ROAD_V,\r
+                                          ROAD_V, ROAD_V, ROAD_V, ROAD_V,  };\r
+\r
+    roads_left=random (MAX_ROADS-MIN_ROADS)+MIN_ROADS;\r
+\r
+        /************************************************\\r
+         *     PLACE FIRST TILE AT WORLD SCREEN EDGE    *\r
+        \************************************************/\r
+\r
+    while (roads_left-- && failed_roads<=MAX_FAILS)\r
+    {\r
+            /* PICK RANDOM ENTRY POINT */\r
+        keepgoing=TRUE;\r
+        entry=random(NUM_DIRECTIONS)+FIRST_DIRECTION;\r
+        switch (entry)\r
+        {\r
+/********/  case DIRECTION_UP: /* TOP ENTRY */\r
+\r
+            x=random(WORLD_WIDTH); y=0;\r
+            current_tile=terrain[WORLD_TILE(x,y)];\r
+\r
+            if (!isroad(current_tile))\r
+            {\r
+                current_tile=terrain[WORLD_TILE(x,y)]=\r
+                    roads_to_up[random(ROAD_LEADERS)];\r
+                direction=roadexit(current_tile, DIRECTION_DOWN);\r
+                               break;\r
+            }\r
+\r
+            else\r
+            {\r
+                roads_left++;\r
+                failed_roads++;\r
+                keepgoing=FALSE;\r
+                break;\r
+            }\r
+\r
+/********/  case DIRECTION_DOWN: /* BOTTOM ENTRY */\r
+\r
+                       x=random(WORLD_WIDTH); y=WORLD_HEIGHT-1;\r
+            current_tile=terrain[WORLD_TILE(x,y)];\r
+\r
+            if (!isroad(current_tile))\r
+            {\r
+                current_tile=terrain[WORLD_TILE(x,y)]=\r
+                    roads_to_down[random(ROAD_LEADERS)];\r
+                direction=roadexit(current_tile, DIRECTION_UP);\r
+            }\r
+\r
+            else\r
+            {\r
+                roads_left++;\r
+                               failed_roads++;\r
+                keepgoing=FALSE;\r
+            }\r
+            break;\r
+\r
+/********/  case DIRECTION_LEFT: /* LEFT ENTRY */\r
+\r
+            x=0; y=random(WORLD_HEIGHT);\r
+            current_tile=terrain[WORLD_TILE(x,y)];\r
+\r
+            if (!isroad(current_tile))\r
+            {\r
+                current_tile=terrain[WORLD_TILE(x,y)]=\r
+                                       roads_to_left[random(ROAD_LEADERS)];\r
+                direction=roadexit(current_tile, DIRECTION_RIGHT);\r
+            }\r
+\r
+            else\r
+            {\r
+                roads_left++;\r
+                failed_roads++;\r
+                keepgoing=FALSE;\r
+            }\r
+            break;\r
+\r
+/********/  case DIRECTION_RIGHT: /* RIGHT ENTRY */\r
+\r
+            x=WORLD_WIDTH-1; y=random(WORLD_HEIGHT);\r
+            current_tile=terrain[WORLD_TILE(x,y)];\r
+\r
+            if (!isroad(current_tile))\r
+            {\r
+                current_tile=terrain[WORLD_TILE(x,y)]=\r
+                    roads_to_right[random(ROAD_LEADERS)];\r
+                direction=roadexit(current_tile, DIRECTION_LEFT);\r
+            }\r
+\r
+            else\r
+            {\r
+                               roads_left++;\r
+                failed_roads++;\r
+                keepgoing=FALSE;\r
+            }\r
+            break;\r
+        }\r
+\r
+        /************************************************\\r
+         * PLACE SUBSEQUENT TILES AWAY FROM ENTRY POINT *\r
+        \************************************************/\r
+\r
+        while (keepgoing)\r
+        {\r
+                       switch (direction)\r
+            {\r
+/********/      case DIRECTION_UP: /* UP */\r
+\r
+                if (--y<0)\r
+                {\r
+                    keepgoing=FALSE;\r
+                    break;\r
+                }\r
+\r
+                current_tile=terrain[WORLD_TILE(x,y)];\r
+                if (!isroad(current_tile))\r
+                {\r
+                    current_tile=terrain[WORLD_TILE(x,y)]=\r
+                        roads_to_down[random(ROAD_LEADERS)];\r
+                    direction=roadexit(current_tile, DIRECTION_UP);\r
+                }\r
+\r
+                else /* INTERSECTION OCCURS */\r
+                {\r
+                    if (random(100)>=CHANCE_CROSSROAD &&\r
+                        terrain[WORLD_TILE(x,y-1)]==EMPTY_TILE)\r
+                    {\r
+                        keepgoing=FALSE;\r
+                        terrain[WORLD_TILE(x,y)]=makeintersection\r
+                            (current_tile, DIRECTION_DOWN);\r
+                                       }\r
+\r
+                    else /* CROSSROAD AND CONTINUE */\r
+                    {\r
+                        terrain[WORLD_TILE(x,y)]=makeintersection\r
+                            (makeintersection(current_tile, DIRECTION_UP),\r
+                            DIRECTION_DOWN); /* ADD BOTH RAMPS */\r
+                    }\r
+                }\r
+                break;\r
+\r
+/********/      case DIRECTION_DOWN:  /* DOWN */\r
+\r
+                               if (++y>=WORLD_HEIGHT)\r
+                {\r
+                    keepgoing=FALSE;\r
+                    break;\r
+                }\r
+\r
+                current_tile=terrain[WORLD_TILE(x,y)];\r
+                if (!isroad(current_tile))\r
+                {\r
+                    current_tile=terrain[WORLD_TILE(x,y)]=\r
+                        roads_to_up[random(ROAD_LEADERS)];\r
+                    direction=roadexit(current_tile, DIRECTION_DOWN);\r
+                }\r
+\r
+                else /* INTERSECTION OCCURS */\r
+                {\r
+                    if (random(100)>=CHANCE_CROSSROAD &&\r
+                        terrain[WORLD_TILE(x,y+1)]==EMPTY_TILE)\r
+\r
+                    {\r
+                        keepgoing=FALSE;\r
+                        terrain[WORLD_TILE(x,y)]=makeintersection\r
+                            (current_tile, DIRECTION_UP);\r
+                    }\r
+\r
+                    else /* CROSSROAD AND CONTINUE */\r
+                                       {\r
+                        terrain[WORLD_TILE(x,y)]=makeintersection\r
+                            (makeintersection(current_tile, DIRECTION_DOWN),\r
+                            DIRECTION_UP); /* ADD BOTH RAMPS */\r
+                    }\r
+                }\r
+                break;\r
+\r
+/********/      case DIRECTION_LEFT: /* LEFT */\r
+\r
+                if (--x<0)\r
+                {\r
+                    keepgoing=FALSE;\r
+                                       break;\r
+                }\r
+\r
+                current_tile=terrain[WORLD_TILE(x,y)];\r
+                if (!isroad(current_tile))\r
+                {\r
+                    current_tile=terrain[WORLD_TILE(x,y)]=\r
+                        roads_to_right[random(ROAD_LEADERS)];\r
+                    direction=roadexit(current_tile, DIRECTION_LEFT);\r
+                }\r
+\r
+                else /* INTERSECTION OCCURS */\r
+                {\r
+                                       if (random(100)>=CHANCE_CROSSROAD &&\r
+                        terrain[WORLD_TILE(x-1,y)]==EMPTY_TILE)\r
+\r
+                    {\r
+                        keepgoing=FALSE;\r
+                        terrain[WORLD_TILE(x,y)]=makeintersection\r
+                            (current_tile, DIRECTION_RIGHT);\r
+                    }\r
+\r
+                    else /* CROSSROAD AND CONTINUE */\r
+                    {\r
+                        terrain[WORLD_TILE(x,y)]=makeintersection\r
+                            (makeintersection(current_tile, DIRECTION_LEFT),\r
+                                                       DIRECTION_RIGHT); /* ADD BOTH RAMPS */\r
+                    }\r
+                }\r
+                break;\r
+\r
+/********/      case DIRECTION_RIGHT: /* RIGHT */\r
+\r
+                if (++x>=WORLD_WIDTH)\r
+                {\r
+                    keepgoing=FALSE;\r
+                    break;\r
+                }\r
+\r
+                current_tile=terrain[WORLD_TILE(x,y)];\r
+                if (!isroad(current_tile))\r
+                {\r
+                    current_tile=terrain[WORLD_TILE(x,y)]=\r
+                        roads_to_left[random(ROAD_LEADERS)];\r
+                    direction=roadexit(current_tile, DIRECTION_RIGHT);\r
+                }\r
+\r
+                else /* INTERSECTION OCCURS */\r
+                {\r
+                    if (random(100)>=CHANCE_CROSSROAD &&\r
+                        terrain[WORLD_TILE(x+1,y)]==EMPTY_TILE)\r
+\r
+                                       {\r
+                        keepgoing=FALSE;\r
+                        terrain[WORLD_TILE(x,y)]=makeintersection\r
+                            (current_tile, DIRECTION_LEFT);\r
+                    }\r
+\r
+                    else /* CROSSROAD AND CONTINUE */\r
+                    {\r
+                        terrain[WORLD_TILE(x,y)]=makeintersection\r
+                            (makeintersection(current_tile, DIRECTION_RIGHT),\r
+                            DIRECTION_LEFT); /* ADD BOTH RAMPS */\r
+                    }\r
+                }\r
+                               break;\r
+            } /* "DIRECTION" HERE */\r
+        } /* STOP "KEEPGOING" HERE */\r
+    }\r
+}\r
+\r
+/*\r
+ *\r
+ * Returns the unspecified direction in an angled road.\r
+ *\r
+ */\r
+int roadexit (int road, int direction)\r
+{\r
+       switch (direction)\r
+    {\r
+        case DIRECTION_UP: /* up */\r
+        if (road==ROAD_V)  return DIRECTION_UP;\r
+        if (road==ROAD_UL) return DIRECTION_LEFT;\r
+        if (road==ROAD_UR) return DIRECTION_RIGHT;\r
+        break;\r
+\r
+        case DIRECTION_DOWN: /* down */\r
+        if (road==ROAD_V)  return DIRECTION_DOWN;\r
+        if (road==ROAD_DL) return DIRECTION_LEFT;\r
+        if (road==ROAD_DR) return DIRECTION_RIGHT;\r
+        break;\r
+\r
+        case DIRECTION_LEFT: /* left */\r
+        if (road==ROAD_DR) return DIRECTION_UP;\r
+        if (road==ROAD_UR) return DIRECTION_DOWN;\r
+        if (road==ROAD_H)  return DIRECTION_LEFT;\r
+        break;\r
+\r
+        case DIRECTION_RIGHT: /* right */\r
+        if (road==ROAD_DL) return DIRECTION_UP;\r
+        if (road==ROAD_UL) return DIRECTION_DOWN;\r
+        if (road==ROAD_H)  return DIRECTION_RIGHT;\r
+        break;\r
+    }\r
+\r
+    fg_music ("A$");\r
+    return ERROR_TILE;\r
+}\r
+\r
+/*\r
+ *\r
+ * Adds a road (ramp) to the specified road, and returns the\r
+ * tile number of what the new road is made of.\r
+ *\r
+ */\r
+int makeintersection (int road, int ramp)\r
+{\r
+       switch (road)\r
+    {\r
+        case ROAD_X:  /* Å */\r
+        return ROAD_X;\r
+\r
+        case ROAD_V:  /* ³ */\r
+        if (ramp==DIRECTION_LEFT) return ROAD_TL;\r
+        if (ramp==DIRECTION_RIGHT) return ROAD_TR;\r
+        return ROAD_V;\r
+\r
+        case ROAD_H:  /* Ä */\r
+        if (ramp==DIRECTION_UP) return ROAD_TU;\r
+        if (ramp==DIRECTION_DOWN) return ROAD_TD;\r
+               return ROAD_H;\r
+\r
+        case ROAD_UR: /* Ú */\r
+        if (ramp==DIRECTION_UP) return ROAD_TR;\r
+        if (ramp==DIRECTION_LEFT) return ROAD_TD;\r
+        return ROAD_UR;\r
+\r
+        case ROAD_UL: /* ¿ */\r
+        if (ramp==DIRECTION_UP) return ROAD_TL;\r
+        if (ramp==DIRECTION_RIGHT) return ROAD_TD;\r
+        return ROAD_UL;\r
+\r
+        case ROAD_DR: /* À */\r
+               if (ramp==DIRECTION_DOWN) return ROAD_TR;\r
+        if (ramp==DIRECTION_LEFT) return ROAD_TU;\r
+        return ROAD_DR;\r
+\r
+        case ROAD_DL: /* Ù */\r
+        if (ramp==DIRECTION_DOWN) return ROAD_TL;\r
+        if (ramp==DIRECTION_RIGHT) return ROAD_TU;\r
+        return ROAD_DL;\r
+\r
+        case ROAD_TL: /* ´ */\r
+        if (ramp==DIRECTION_RIGHT) return ROAD_X;\r
+        return ROAD_TL;\r
+\r
+               case ROAD_TR: /* Ã */\r
+        if (ramp==DIRECTION_LEFT) return ROAD_X;\r
+        return ROAD_TR;\r
+\r
+        case ROAD_TU: /* Á */\r
+        if (ramp==DIRECTION_DOWN) return ROAD_X;\r
+        return ROAD_TU;\r
+\r
+        case ROAD_TD: /* Â */\r
+        if (ramp==DIRECTION_UP) return ROAD_X;\r
+        return ROAD_TD;\r
+    }\r
+\r
+       fg_music ("A$");\r
+    return ERROR_TILE;\r
+}\r
+\r
+/*\r
+    AI USED IN ROAD FUNCTIONS:\r
+    pick random entry point on one of the four sides\r
+    place subsequent tiles with tendency to move from screen\r
+    place subsequent tiles with tendency use V or H pieces if just used\r
+    if hit existing tile, either\r
+    a) cross over road and continue, using X tile\r
+    b) terminate road with a T\r
+    repeat until MAX_ROADS complete\r
+*/\r
+\r
+/*\r
+ *\r
+ * Adds edges to places where grass and dirt meet.\r
+ * Called by init_background() to liven up background display.\r
+ *\r
+ */\r
+void add_dirt_edges (void)\r
+{\r
+    register int x, y;\r
+    int tile;\r
+\r
+    /* ADD 90 DEGREE EDGES */\r
+    for (y=0; y<WORLD_HEIGHT; y++)\r
+    for (x=0; x<WORLD_WIDTH; x++)\r
+    if (isdirt(topography[WORLD_TILE(x,y)]))\r
+    {\r
+        tile=0; /* ADD UP BINARY TILE NUMBER */\r
+        if (y-1>=0) tile+=isgrass(topography[WORLD_TILE(x,y-1)]);\r
+        if (x+1<WORLD_WIDTH) tile+=isgrass(topography[WORLD_TILE(x+1,y)])*2;\r
+        if (y+1<WORLD_HEIGHT) tile+=isgrass(topography[WORLD_TILE(x,y+1)])*4;\r
+        if (x-1>=0) tile+=isgrass(topography[WORLD_TILE(x-1,y)])*8;\r
+\r
+        /* CONVERT BINARY TILE NUMBER TO ACTUAL */\r
+        switch (tile)\r
+        {\r
+            case 1:  tile=DIRTEDGE_U;    break;\r
+            case 2:  tile=DIRTEDGE_R;    break;\r
+            case 3:  tile=DIRTEDGE_UR;   break;\r
+            case 4:  tile=DIRTEDGE_D;    break;\r
+            case 5:  tile=DIRTEDGE_UD;   break;\r
+            case 6:  tile=DIRTEDGE_RD;   break;\r
+            case 7:  tile=DIRTEDGE_URD;  break;\r
+            case 8:  tile=DIRTEDGE_L;    break;\r
+            case 9:  tile=DIRTEDGE_UL;   break;\r
+            case 10: tile=DIRTEDGE_RL;   break;\r
+            case 11: tile=DIRTEDGE_URL;  break;\r
+            case 12: tile=DIRTEDGE_DL;   break;\r
+            case 13: tile=DIRTEDGE_UDL;  break;\r
+            case 14: tile=DIRTEDGE_RDL;  break;\r
+            case 15: tile=DIRTEDGE_URDL; break;\r
+            case 0:  tile=topography[WORLD_TILE(x,y)]; break; /* NO CHANGE */\r
+        }\r
+        topography[WORLD_TILE(x,y)]=tile; /* CHANGE TILE */\r
+    }\r
+}\r
+\r