@@ -137,6 +137,12 @@ class LevelGen
137
137
// Level tiles and room info
138
138
//
139
139
Cell data[ MAP_WIDTH ][ MAP_HEIGHT ];
140
+
141
+ //
142
+ // Used for celular automata
143
+ //
144
+ uint8_t map_new[ MAP_WIDTH ][ MAP_HEIGHT ];
145
+ uint8_t map_old[ MAP_WIDTH ][ MAP_HEIGHT ];
140
146
};
141
147
142
148
typedef enum {
@@ -1034,6 +1040,125 @@ static bool level_gen_create_first_room(Gamep g, LevelGen *l, bool debug)
1034
1040
return true ;
1035
1041
}
1036
1042
1043
+ static void cave_generation (Gamep g, class LevelGen *l, int r1, int r2)
1044
+ {
1045
+ uint8_t x, y;
1046
+
1047
+ if (0 ) {
1048
+ printf (" before:\n " );
1049
+ for (y = 2 ; y < MAP_HEIGHT; y++) {
1050
+ for (x = 2 ; x < MAP_WIDTH; x++) {
1051
+ if (l->map_new [ x ][ y ]) {
1052
+ printf (" x" );
1053
+ } else {
1054
+ printf (" " );
1055
+ }
1056
+ }
1057
+ printf (" \n " );
1058
+ }
1059
+ printf (" \n " );
1060
+ }
1061
+
1062
+ for (x = 2 ; x < MAP_WIDTH; x++) {
1063
+ for (y = 2 ; y < MAP_HEIGHT; y++) {
1064
+
1065
+ uint8_t adjcount = 0 ;
1066
+
1067
+ #define ADJ (i, j ) adjcount += l->map_new[ x + i ][ y + j ];
1068
+
1069
+ ADJ (-1 , -1 );
1070
+ ADJ (-1 , 0 );
1071
+ ADJ (-1 , 1 );
1072
+
1073
+ ADJ (0 , -1 );
1074
+ ADJ (0 , 0 );
1075
+ ADJ (0 , 1 );
1076
+
1077
+ ADJ (1 , -1 );
1078
+ ADJ (1 , 0 );
1079
+ ADJ (1 , 1 );
1080
+
1081
+ if (adjcount >= r1) {
1082
+ continue ;
1083
+ }
1084
+
1085
+ ADJ (-2 , -1 );
1086
+ ADJ (-2 , 0 );
1087
+ ADJ (-2 , 1 );
1088
+
1089
+ ADJ (-1 , -2 );
1090
+ ADJ (-1 , 2 );
1091
+
1092
+ ADJ (0 , -2 );
1093
+ ADJ (0 , 2 );
1094
+
1095
+ ADJ (1 , -2 );
1096
+ ADJ (1 , 2 );
1097
+
1098
+ ADJ (2 , -1 );
1099
+ ADJ (2 , 0 );
1100
+ ADJ (2 , 1 );
1101
+
1102
+ //
1103
+ // Adjust for the grow threshold for rock or flow.
1104
+ //
1105
+ if (adjcount <= r2) {
1106
+ //
1107
+ // map_old set to 0 already.
1108
+ //
1109
+ } else {
1110
+ l->map_old [ x ][ y ] = 1 ;
1111
+ }
1112
+ }
1113
+ }
1114
+
1115
+ if (0 ) {
1116
+ printf (" after:\n " );
1117
+ for (y = 2 ; y < MAP_HEIGHT; y++) {
1118
+ for (x = 2 ; x < MAP_WIDTH; x++) {
1119
+ if (l->map_new [ x ][ y ]) {
1120
+ printf (" x" );
1121
+ } else {
1122
+ printf (" " );
1123
+ }
1124
+ }
1125
+ printf (" \n " );
1126
+ }
1127
+ printf (" \n " );
1128
+ }
1129
+ }
1130
+
1131
+ static void level_gen_add_water (Gamep g, class LevelGen *l, uint32_t fill_prob, int r1, int r2, int map_generations)
1132
+ {
1133
+ uint8_t x, y, i;
1134
+
1135
+ memset (l->map_new , 0 , sizeof (l->map_new ));
1136
+ for (x = 2 ; x < MAP_WIDTH - 2 ; x++) {
1137
+ for (y = 2 ; y < MAP_HEIGHT - 2 ; y++) {
1138
+ if (pcg_random_range (0 , 10000 ) < fill_prob) {
1139
+ l->map_new [ x ][ y ] = 1 ;
1140
+ }
1141
+ }
1142
+ }
1143
+
1144
+ for (i = 0 ; i < map_generations; i++) {
1145
+ cave_generation (g, l, r1, r2);
1146
+ memcpy (l->map_new , l->map_old , sizeof (l->map_old ));
1147
+ memset (l->map_old , 0 , sizeof (l->map_old ));
1148
+ }
1149
+
1150
+ for (x = 2 ; x < MAP_WIDTH - 2 ; x++) {
1151
+ for (y = 2 ; y < MAP_HEIGHT - 2 ; y++) {
1152
+ if (l->map_new [ x ][ y ]) {
1153
+ if (l->data [ x ][ y ].c == CHARMAP_EMPTY) {
1154
+ l->data [ x ][ y ].c = CHARMAP_SHALLOW_WATER;
1155
+ l->data [ x ][ y ].room = nullptr ;
1156
+ }
1157
+ }
1158
+ }
1159
+ }
1160
+ }
1161
+
1037
1162
//
1038
1163
// Create rooms from the current seed
1039
1164
//
@@ -1449,6 +1574,11 @@ static class LevelGen *level_gen(Gamep g, int which)
1449
1574
//
1450
1575
level_gen_add_chasms_around_bridges (g, l, debug);
1451
1576
1577
+ //
1578
+ // Add water
1579
+ //
1580
+ level_gen_add_water (g, l, 1000 , 9 , 3 , 3 );
1581
+
1452
1582
return l;
1453
1583
}
1454
1584
0 commit comments