diff --git a/assets-fx/large_tileset.png b/assets-fx/large_tileset.png index e0b07bc..34400e0 100644 Binary files a/assets-fx/large_tileset.png and b/assets-fx/large_tileset.png differ diff --git a/assets-fx/mini_tileset.png b/assets-fx/mini_tileset.png index 6b5f37b..0023965 100644 Binary files a/assets-fx/mini_tileset.png and b/assets-fx/mini_tileset.png differ diff --git a/src/calccity.c b/src/calccity.c index 3c6d68b..f715edb 100644 --- a/src/calccity.c +++ b/src/calccity.c @@ -5,7 +5,7 @@ const struct building buildings[42] = { // Menu 1 { - (char []){48, 49, 110, 111, 112, 113, 114, 120, 121, 122, 123, 124, 130, 131, 132, 133, 134, -1}, + (char []){110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, -1}, 10, // cost {1, 1}, //size {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // stat @@ -15,7 +15,7 @@ const struct building buildings[42] = { }, { - (char []){139, -1}, + (char []){127, -1}, 15, {1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, @@ -157,7 +157,7 @@ const struct building buildings[42] = { // Menu 2 { - (char []){83, 80, 81, 82, 90, 91, 92, 93, 100, 101, 102, -1}, + (char []){80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, -1}, 10, {1, 1}, {0, 0, 0, 0, 0, 50, 0, 0, 0, 10, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0}, @@ -187,7 +187,7 @@ const struct building buildings[42] = { }, { - (char []){87, 84, 85, 86, 94, 95, 96, 97, 104, 105, 106, -1}, + (char []){95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, -1}, 50, {1, 1}, {0, 0, 0, 0, 0, 100, 0, 0, 0, 1, 0, 0, 0, 0, 0, 10, 0, 0, 5, 0, 0, 0, 0}, @@ -220,7 +220,7 @@ const struct building buildings[42] = { (char []){50, 51, 60, 61, -1}, 25000, {2, 2}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 1, 0, 0, 0, 0, 100, 1000, 0, 0, 250000, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 1, 30, 1, 0, 0, 0, 0, 100, 1000, 0, 0, 250000, 0, 0, 0}, {0, 0, 0}, {0, 0, 0, 0}, "CENTALE NUCLEAIRE" @@ -357,7 +357,7 @@ const struct building buildings[42] = { }, - // Others buildings + // Large buildings { (char []){5, 6, 15, 16, -1}, 200, diff --git a/src/calccity.h b/src/calccity.h index e477f25..1f829aa 100644 --- a/src/calccity.h +++ b/src/calccity.h @@ -74,8 +74,7 @@ struct camera struct map { unsigned char data[50][50]; - - unsigned char id[50][50]; + char id[50][50]; }; diff --git a/src/core.c b/src/core.c index faccd66..a9cb754 100644 --- a/src/core.c +++ b/src/core.c @@ -57,64 +57,24 @@ void default_values(struct calccity *calccity, struct camera *camera, struct map // Water if ((x * y == 0) || (x == 49 || y == 49)) { - map->data[y][x] = 139; + map->data[y][x] = 127; map->id[y][x] = 1; } // Ground else { - map->data[y][x] = 48 + rand() % 2; + map->data[y][x] = 125 + rand() % 2; map->id[y][x] = 0; - } - - // Shorelines - switch (y) - { - case 1: - switch (x) - { - case 1: - map->data[y][x] = 110; - break; - - case 48: - map->data[y][x] = 112; - break; - - default: - if (x != 0 && x != 49) map->data[y][x] = 111; - break; - } - break; - - case 48: - switch (x) - { - case 1: - map->data[y][x] = 130; - break; - - case 48: - map->data[y][x] = 132; - break; - - default: - if (x != 0 && x != 49) map->data[y][x] = 131; - break; - } - break; - - default: - if (y != 0 && y != 49) - { - if (x == 1) map->data[y][x] = 120; - if (x == 48) map->data[y][x] = 122; - } - } + } } } + for (int y = 0; y < 50; y ++) + { + for (int x = 0; x < 50; x ++) + check(map, x, y); + } } @@ -154,7 +114,47 @@ void next_step(struct calccity *calccity, struct map *map) } } - // Disasters gestion soon™ + if (calccity->disaster) + { + // Firehazard + if (calccity->stat[7] > 500 && rand() % 1000 == 0) + { + display_message("UN INCENDIE A RAVAGE VOTRE VILLE."); + disaster(calccity, map, calccity->stat[7]); + update_stat(calccity, map); + } + + // Nuclear disaster + if (calccity->stat[8] >= 1 && rand() % 10000 == 0) + { + display_message("UN ACCIDENT NUCLEAIRE A RAVAGE VOTRE VILLE."); + disaster(calccity, map, calccity->stat[8] * 100); + update_stat(calccity, map); + } + + // Earthquake + if (rand() % 10000 == 0) + { + display_message("UN TREMBLEMENT DE TERRE A RAVAGE VOTRE VILLE."); + disaster(calccity, map, rand() % 10); + update_stat(calccity, map); + } + + // Treasure + if (calccity->misc[0] > 1000 && rand() % 1000 == 0) + { + if (rand() % 2) + { + display_message("DES INVESTISSEMENT AUDACIEUX VOUS ONT RAPPORTES 1000$ !"); + calccity->misc[0] += 1000; + } + else + { + display_message("DES INVESTISSEMENT FOIREUX VOUS ONT FAIT PERDRE 1000$."); + calccity->misc[0] -= 1000; + } + } + } } @@ -229,34 +229,47 @@ void main_loop(struct calccity *calccity, struct camera *camera, struct map *map exit_build_mode(camera, &build_mode); // Build validation - if (key == KEY_SHIFT && can_build(calccity, camera, map, &building)) + if (key == KEY_SHIFT) { unsigned short loc_x = building.size[0] * floor(camera->x + camera->cursor_x / (floor(camera->cursor_size[0] / 8) + 1)); unsigned short loc_y = building.size[1] * floor(camera->y + camera->cursor_y / (floor(camera->cursor_size[1] / 8) + 1)); + unsigned char index = 0; - if (build_mode == 5 || build_mode == 8 || build_mode == 11 || build_mode == 27 || build_mode == 28 || build_mode == 29) + if (can_build(calccity, map, &building, loc_x, loc_y, &index)) { - building = large_building(map, build_mode, &loc_x, &loc_y); - for (int y = loc_y; y < loc_y + building.size[1]; y ++) + // Large buildings gestion + if (build_mode == 5 || build_mode == 8 || build_mode == 11 || build_mode == 27 || build_mode == 28 || build_mode == 29) { - for (int x = loc_x; x < loc_x + building.size[0]; x ++) - map->id[y][x] = 0; + building = large_building(map, &build_mode, &loc_x, &loc_y); + for (int y = loc_y; y < loc_y + building.size[1]; y ++) + { + for (int x = loc_x; x < loc_x + building.size[0]; x ++) + map->id[y][x] = 0; + } + update_stat(calccity, map); } + + // Destruction + if (map->id[loc_y][loc_x] != 1 && build_mode == 0) + destruction(map, loc_x, loc_y); + + // Other buildings + else + { + for (int y = loc_y; y < loc_y + building.size[1]; y ++) + { + for (int x = loc_x; x < loc_x + building.size[0]; x ++) + { + map->data[y][x] = building.id[index]; + map->id[y][x] = -1; + index ++; + } + } + map->id[loc_y][loc_x] = build_mode; + } + calccity->misc[0] -= building.cost; update_stat(calccity, map); } - - unsigned char index = 0; - for (int y = loc_y; y < loc_y + building.size[1]; y ++) - { - for (int x = loc_x; x < loc_x + building.size[0]; x ++) - { - map->data[y][x] = building.id[index]; - index ++; - } - } - map->id[loc_y][loc_x] = build_mode; - calccity->misc[0] -= building.cost; - update_stat(calccity, map); } } @@ -315,10 +328,8 @@ void keyboard_managment(struct camera *camera, const int key, const int build_mo } -bool can_build(struct calccity *calccity, struct camera *camera, struct map *map, struct building *building) +bool can_build(struct calccity *calccity, struct map *map, struct building *building, const unsigned short loc_x, const unsigned short loc_y, unsigned char *index) { - unsigned short loc_x = building->size[0] * floor(camera->x + camera->cursor_x / (floor(camera->cursor_size[0] / 8) + 1)); - unsigned short loc_y = building->size[1] * floor(camera->y + camera->cursor_y / (floor(camera->cursor_size[1] / 8) + 1)); // Not enougth money if (calccity->misc[0] < building->cost) @@ -327,25 +338,38 @@ bool can_build(struct calccity *calccity, struct camera *camera, struct map *map return false; } + // harbor's orientation + if (building->id[0] == 62) + { + *index = check_harbor(map, loc_x, loc_y); + if (*index == 4) + { + display_message("VOUS DEVEZ CONSTUIRE LES PORTS A PROXIMITE DE L'EAU"); + return false; + } + } for (int y = loc_y; y < loc_y + building->size[1]; y ++) { for (int x = loc_x; x < loc_x + building->size[0]; x ++) { // Build on water - if (map->data[y][x] == 139) + if (map->id[y][x] == 1 && building->id[0] != 110) { display_message("VOUS NE POUVEZ PAS CONSTRUIRE SUR L'EAU."); return false; } // Build on another building - if (map->data[y][x] != 48 && map->data[y][x] != 49 && map->data[y][x] < 110 && building->id[0] != 48) + if (map->id[y][x] != 0 && building->id[0] != 110) { display_message("VOUS NE POUVEZ PAS CONSTRUIRE SUR BATIMENT EXISTANT."); return false; } + // Build dirt on dirt or water on water + if ((building->id[0] == 110 && map->id[y][x] == 0) || (building->id[0] == 127 && map->id[y][x] == 1)) + return false; } } @@ -361,7 +385,7 @@ void exit_build_mode(struct camera *camera, int *build_mode) } -struct building large_building(struct map *map, const int build_mode, short unsigned int *loc_x, short unsigned int *loc_y) +struct building large_building(struct map *map, int *build_mode, short unsigned int *loc_x, short unsigned int *loc_y) { extern const struct building buildings[42]; const short unsigned int Y[16] = {*loc_y - 1, *loc_y - 1, *loc_y, *loc_y, *loc_y - 1, *loc_y - 1, *loc_y, *loc_y, *loc_y, *loc_y, *loc_y + 1, *loc_y + 1, *loc_y, *loc_y, *loc_y + 1, *loc_y + 1}; @@ -374,7 +398,7 @@ struct building large_building(struct map *map, const int build_mode, short unsi { short unsigned int y = Y[4 * i + j]; short unsigned int x = X[4 * i + j]; - if (map->id[y][x] == build_mode) check ++; + if (map->id[y][x] == *build_mode) check ++; } if (check == 3) @@ -382,41 +406,40 @@ struct building large_building(struct map *map, const int build_mode, short unsi *loc_x = X[4 * i]; *loc_y = Y[4 * i]; - switch (build_mode) + switch (*build_mode) { case 5: - return buildings[35]; + *build_mode = 35; break; case 8: - return buildings[36]; + *build_mode = 36; break; case 11: - return buildings[37]; + *build_mode = 37; break; case 27: - return buildings[38]; + *build_mode = 38; break; case 28: - return buildings[39]; + *build_mode = 39; break; case 29: - return buildings[40]; + *build_mode = 40; break; } } } - return buildings[build_mode]; + return buildings[*build_mode]; } void update_stat(struct calccity *calccity, struct map *map) -{ - +{ extern const struct building buildings[42]; // Reset stat @@ -428,6 +451,10 @@ void update_stat(struct calccity *calccity, struct map *map) { for (int x = 0; x < 50; x ++) { + // Checking shorelines, roads and railways + check(map, x, y); + + // Update stat if (map->id[y][x] > 1) { struct building building = buildings[map->id[y][x]]; @@ -595,4 +622,178 @@ void end_year(struct calccity *calccity) while (key != KEY_ALPHA) key = getkey_opt(opt, &timeout).key; +} + + +void check(struct map *map, const int x, const int y) +{ + switch (map->id[y][x]) + { + // shorelines + case 0: + int shore_id = 110; + if ((y - 1 >= 0) && map->id[y - 1][x] != 1) shore_id += 8; + if ((y + 1 < 50) && map->id[y + 1][x] != 1) shore_id += 1; + if ((x - 1 >= 0) && map->id[y][x - 1] != 1) shore_id += 4; + if ((x + 1 < 50) && map->id[y][x + 1] != 1) shore_id += 2; + + if (map->data[y][x] != 125 && map->data[y][x] != 126 && shore_id == 125) shore_id += rand() % 2; + map->data[y][x] = shore_id; + break; + + // roads + case 15: + int road_id = 80; + if ((y - 1 >= 0) && map->id[y - 1][x] == 15) road_id += 8; + if ((y + 1 < 50) && map->id[y + 1][x] == 15) road_id += 1; + if ((x - 1 >= 0) && map->id[y][x - 1] == 15) road_id += 4; + if ((x + 1 < 50) && map->id[y][x + 1] == 15) road_id += 2; + + if (road_id > 80) road_id --; + map->data[y][x] = road_id; + break; + + // railways + case 18: + int rail_id = 95; + if ((y - 1 >= 0) && map->id[y - 1][x] == 18) rail_id += 8; + if ((y + 1 < 50) && map->id[y + 1][x] == 18) rail_id += 1; + if ((x - 1 >= 0) && map->id[y][x - 1] == 18) rail_id += 4; + if ((x + 1 < 50) && map->id[y][x + 1] == 18) rail_id += 2; + + if (rail_id > 95) rail_id --; + map->data[y][x] = rail_id; + break; + } +} + + +int check_harbor(struct map *map, const int x, const int y) +{ + if (map->id[y][x - 1] == 1) return 0; + if (map->id[y][x + 1] == 1) return 1; + if (map->id[y - 1][x] == 1) return 2; + if (map->id[y + 1][x] == 1) return 3; + + return 4; +} + + +int get_reference_id(const unsigned char tile_id) +{ + switch (tile_id) + { + case 0: case 1: + return 17; + break; + + case 50: case 51: case 60: case 61: + return 21; + break; + + case 3: case 4: case 13: case 14: + return 22; + break; + + case 42: case 43: case 52: case 53: + return 26; + break; + + case 28: case 29: case 38: case 39: + return 33; + break; + + case 10: case 11: case 20: case 21: + return 34; + break; + + case 5: case 6: case 15: case 16: + return 35; + break; + + case 7: case 8: case 17: case 18: + return 36; + break; + + case 30: case 31: case 40: case 41: + return 37; + break; + + case 26: case 27: case 36: case 37: + return 38; + break; + + case 22: case 23: case 32: case 33: + return 39; + break; + + case 24: case 25: case 34: case 35: + return 40; + break; + + case 2: case 12: + return 41; + break; + } + return 0; +} + + +void destruction(struct map *map, int loc_x, int loc_y) +{ + extern const struct building buildings[42]; + + unsigned char ref_id; + if (map->id[loc_y][loc_x] == -1) ref_id = get_reference_id(map->data[loc_y][loc_x]); + else ref_id = map->id[loc_y][loc_x]; + + const struct building building = buildings[ref_id]; + const int ref_x = loc_x, ref_y = loc_y; + + if (map->id[ref_y - 1][ref_x] == ref_id) loc_y --; + if (map->id[ref_y - 1][ref_x - 1] == ref_id){loc_x --; loc_y --;} + if (map->id[ref_y][ref_x - 1] == ref_id) loc_x --; + + for (int y = loc_y; y < loc_y + building.size[1]; y ++) + { + for (int x = loc_x; x < loc_x + building.size[0]; x ++) + { + map->data[y][x] = 125 + rand() % 2; + map->id[y][x] = 0; + } + } +} + + +void disaster(struct calccity *calccity, struct map *map, const int destruction_rate) +{ + for (int y = 0; y < 50; y ++) + { + for (int x = 0; x < 50; x ++) + { + if (map->id[y][x] > 1 && rand() % destruction_rate <= destruction_rate / 4) + { + map->id[y][x] = 0; + map->data[y][x] = 125 + rand() % 2; + + // Large building check + if (map->id[y][x + 1] == -1) + { + map->id[y][x + 1] = 0; + map->data[y][x + 1] = 125 + rand() % 2; + } + if (map->id[y + 1][x + 1] == -1) + { + map->id[y + 1][x + 1] = 0; + map->data[y + 1][x + 1] = 125 + rand() % 2; + } + if (map->id[y + 1][x] == -1) + { + map->id[y][x + 1] = 0; + map->data[y][x + 1] = 125 + rand() % 2; + } + calccity->misc[1] = calccity->misc[1] / (rand() % destruction_rate); + } + } + } } \ No newline at end of file diff --git a/src/core.h b/src/core.h index d20b774..391cc98 100644 --- a/src/core.h +++ b/src/core.h @@ -24,13 +24,13 @@ void main_loop(struct calccity *calccity, struct camera *camera, struct map *map void keyboard_managment(struct camera *camera, const int key, const int build_mode); // can_build : test if the build is legit -bool can_build(struct calccity *calccity, struct camera *camera, struct map *map, struct building *building); +bool can_build(struct calccity *calccity, struct map *map, struct building *building, const unsigned short x, const unsigned short y, unsigned char *index); // exit_build_mode : reset build mode and cusor void exit_build_mode(struct camera *camera, int *build_mode); // large_building : detect large buildings and adjust the building's id -struct building large_building(struct map *map, const int build_mode, short unsigned int *loc_x, short unsigned int *loc_y); +struct building large_building(struct map *map, int *build_mode, short unsigned int *loc_x, short unsigned int *loc_y); // update_stat : compute the new stat with buildings void update_stat(struct calccity *calccity, struct map *map); @@ -38,4 +38,19 @@ void update_stat(struct calccity *calccity, struct map *map); // end_year : display the year's balance sheet void end_year(struct calccity *calccity); +// check_shorelines : check the shorelines, roads and railways +void check(struct map *map, const int x, const int y); + +// check_harbor : check the harbor's orientation +int check_harbor(struct map *map, const int x, const int y); + +// get_reference_id : get the id of large buildings +int get_reference_id(const unsigned char tile_id); + +// destruction : manage deconstruction +void destruction(struct map *map, int loc_x, int loc_y); + +// disaster : manage disasters +void disaster(struct calccity *calccity, struct map *map, const int destruction_rate); + #endif /* _CORE_H */ \ No newline at end of file diff --git a/src/display.c b/src/display.c index 91a4412..42f89d1 100644 --- a/src/display.c +++ b/src/display.c @@ -45,7 +45,7 @@ void display_large_map(struct calccity *calccity, struct camera *camera, struct int cam_x = x + camera->x, cam_y = y + camera->y; // Water - if (cam_y > 49 || cam_x > 49 || map->data[cam_y][cam_x] == 139) + if (cam_y > 49 || cam_x > 49 || map->data[cam_y][cam_x] == 127) dsubimage(3 + x * 15, y * 15, &img_large_water, 15 * calccity->blinker_water, 0, 15 * (calccity->blinker_water + 1), 15, DIMAGE_NONE); else { @@ -130,7 +130,7 @@ void display_around(struct calccity *calccity, struct camera *camera, const int } -void display_message(char* message) +void display_message(char *message) { dclear(C_WHITE); @@ -144,13 +144,13 @@ void display_message(char* message) int total_offset = 0; for (int i = 0; i < 5; i ++) { - dtext_opt(3, 7 * i + 8, C_BLACK, C_WHITE, 0, 0, message + total_offset, 20); + dtext_opt(3, 7 * i + 8, C_BLACK, C_WHITE, 0, 0, message + total_offset, 27); int offset = 0; while (message[total_offset + offset] != '\0') offset += 1; if (!offset) break; - else if (offset > 20) total_offset += 20; + else if (offset > 27) total_offset += 27; else total_offset += offset; } diff --git a/src/menus.c b/src/menus.c index a6e55d5..6f801f4 100644 --- a/src/menus.c +++ b/src/menus.c @@ -309,7 +309,7 @@ int menu_6(struct calccity *calccity) while (key != KEY_ALPHA) { - int prcnt = 100 - (calccity->time_speed * 100 / 7500); + int prcnt = 100 - (calccity->time_speed * 100 / 10000); dclear(C_WHITE);