diff --git a/src/building/count.c b/src/building/count.c index 0e11c66c96..f73588ec79 100644 --- a/src/building/count.c +++ b/src/building/count.c @@ -2,9 +2,77 @@ #include "building/building.h" #include "building/monument.h" +#include "core/array.h" #include "city/buildings.h" #include "city/health.h" #include "figure/figure.h" +#include "map/building.h" +#include "map/grid.h" + +static const building_type building_set_farms[] = { + BUILDING_WHEAT_FARM, BUILDING_VEGETABLE_FARM, BUILDING_FRUIT_FARM, BUILDING_OLIVE_FARM, + BUILDING_VINES_FARM, BUILDING_PIG_FARM +}; + +#define BUILDING_SET_SIZE_FARMS (sizeof(building_set_farms) / sizeof(building_type)) + +static const building_type building_set_raw_materials[] = { + BUILDING_MARBLE_QUARRY, BUILDING_IRON_MINE, BUILDING_TIMBER_YARD, BUILDING_CLAY_PIT, + BUILDING_GOLD_MINE, BUILDING_STONE_QUARRY, BUILDING_SAND_PIT +}; + +#define BUILDING_SET_SIZE_RAW_MATERIALS (sizeof(building_set_raw_materials) / sizeof(building_type)) + +static const building_type building_set_workshops[] = { + BUILDING_WINE_WORKSHOP, BUILDING_OIL_WORKSHOP, BUILDING_WEAPONS_WORKSHOP, BUILDING_FURNITURE_WORKSHOP, + BUILDING_POTTERY_WORKSHOP, BUILDING_CONCRETE_MAKER, BUILDING_BRICKWORKS, BUILDING_CITY_MINT +}; + +#define BUILDING_SET_SIZE_WORKSHOPS (sizeof(building_set_workshops) / sizeof(building_type)) + +static const building_type building_set_small_temples[] = { + BUILDING_SMALL_TEMPLE_CERES, BUILDING_SMALL_TEMPLE_NEPTUNE, BUILDING_SMALL_TEMPLE_MERCURY, BUILDING_SMALL_TEMPLE_MARS, + BUILDING_SMALL_TEMPLE_VENUS +}; + +#define BUILDING_SET_SIZE_SMALL_TEMPLES (sizeof(building_set_small_temples) / sizeof(building_type)) + +static const building_type building_set_large_temples[] = { + BUILDING_LARGE_TEMPLE_CERES, BUILDING_LARGE_TEMPLE_NEPTUNE, BUILDING_LARGE_TEMPLE_MERCURY, BUILDING_LARGE_TEMPLE_MARS, + BUILDING_LARGE_TEMPLE_VENUS +}; + +#define BUILDING_SET_SIZE_LARGE_TEMPLES (sizeof(building_set_large_temples) / sizeof(building_type)) + +static const building_type building_set_grand_temples[] = { + BUILDING_GRAND_TEMPLE_CERES, BUILDING_GRAND_TEMPLE_NEPTUNE, BUILDING_GRAND_TEMPLE_MERCURY, BUILDING_GRAND_TEMPLE_MARS, + BUILDING_GRAND_TEMPLE_VENUS, BUILDING_PANTHEON +}; + +#define BUILDING_SET_SIZE_GRAND_TEMPLES (sizeof(building_set_grand_temples) / sizeof(building_type)) + +static const building_type building_set_deco_trees[] = { + BUILDING_PINE_TREE, BUILDING_FIR_TREE, BUILDING_OAK_TREE, BUILDING_ELM_TREE, + BUILDING_FIG_TREE, BUILDING_PLUM_TREE, BUILDING_PALM_TREE, BUILDING_DATE_TREE +}; + +#define BUILDING_SET_SIZE_DECO_TREES (sizeof(building_set_deco_trees) / sizeof(building_type)) + +static const building_type building_set_deco_paths[] = { + BUILDING_PINE_PATH, BUILDING_FIR_PATH, BUILDING_OAK_PATH, BUILDING_ELM_PATH, + BUILDING_FIG_PATH, BUILDING_PLUM_PATH, BUILDING_PALM_PATH, BUILDING_DATE_PATH, + BUILDING_GARDEN_PATH +}; + +#define BUILDING_SET_SIZE_DECO_PATHS (sizeof(building_set_deco_paths) / sizeof(building_type)) + +static const building_type building_set_deco_statues[] = { + BUILDING_GARDENS, BUILDING_GRAND_GARDEN, BUILDING_SMALL_STATUE, BUILDING_MEDIUM_STATUE, + BUILDING_LARGE_STATUE, BUILDING_SMALL_STATUE_ALT, BUILDING_SMALL_STATUE_ALT_B, BUILDING_LEGION_STATUE, + BUILDING_GLADIATOR_STATUE, BUILDING_SMALL_POND, BUILDING_LARGE_POND, BUILDING_DOLPHIN_FOUNTAIN +}; + +#define BUILDING_SET_SIZE_DECO_STATUES (sizeof(building_set_deco_statues) / sizeof(building_type)) int building_count_grand_temples(void) { @@ -48,6 +116,26 @@ int building_count_total(building_type type) return total; } +int building_count_any_total(int active_only) +{ + int total = 0; + for (int id = 1; id < building_count(); id++) { + building *b = building_get(id); + if (b == building_main(b)) { + if (active_only) { + if (building_is_active(b)) { + total++; + } + } else { + if (b->state == BUILDING_STATE_IN_USE || b->state == BUILDING_STATE_CREATED) { + total++; + } + } + } + } + return total; +} + int building_count_upgraded(building_type type) { int upgraded = 0; @@ -59,6 +147,193 @@ int building_count_upgraded(building_type type) return upgraded; } +int building_count_in_area(building_type type, int minx, int miny, int maxx, int maxy) +{ + int grid_area = abs((maxx - minx) * (maxy - miny)); + int array_size = grid_area < building_count() ? grid_area : building_count(); + int *found_buildings = (int *) malloc(array_size * sizeof(int)); + + int total = 0; + for (int x = minx; x <= maxx; x++) { + for (int y = miny; y <= maxy; y++) { + int grid_offset = map_grid_offset(x, y); + int building_id = map_building_at(grid_offset); + if (building_id) { + building *b = building_main(building_get(building_id)); + if (type != BUILDING_ANY && b->type != type) { + continue; + } + if (b->state != BUILDING_STATE_IN_USE && b->state != BUILDING_STATE_CREATED) { + continue; + } + + for (int i = 0; i < total; i++) { + if (found_buildings[i] == b->id) { + continue; + } + } + + found_buildings[total] = b->id; + total++; + } + } + } + + free(found_buildings); + return total; +} + +int building_count_fort_type_in_area(int minx, int miny, int maxx, int maxy, figure_type type) +{ + int grid_area = abs((maxx - minx) * (maxy - miny)); + int array_size = grid_area < building_count() ? grid_area : building_count(); + int *found_buildings = (int *) malloc(array_size * sizeof(int)); + + int total = 0; + for (int x = minx; x <= maxx; x++) { + for (int y = miny; y <= maxy; y++) { + int grid_offset = map_grid_offset(x, y); + int building_id = map_building_at(grid_offset); + if (building_id) { + building *b = building_main(building_get(building_id)); + if (b->type != BUILDING_FORT || b->subtype.fort_figure_type != type) { + continue; + } + if (b->state != BUILDING_STATE_IN_USE && b->state != BUILDING_STATE_CREATED) { + continue; + } + + for (int i = 0; i < total; i++) { + if (found_buildings[i] == b->id) { + continue; + } + } + + found_buildings[total] = b->id; + total++; + } + } + } + + free(found_buildings); + return total; +} + +static int building_count_with_active_check(building_type type, int active_only) +{ + if (active_only) { + return building_count_active(type); + } else { + return building_count_total(type); + } +} + +static int count_all_types_in_set(int active_only, const building_type *set, int count) +{ + int total = 0; + for (int i = 0; i < count; i++) { + building_type type = set[i]; + total += building_count_with_active_check(type, active_only); + } + return total; +} + +static int count_all_types_in_set_in_area(const building_type *set, int count, int minx, int miny, int maxx, int maxy) +{ + int total = 0; + for (int i = 0; i < count; i++) { + building_type type = set[i]; + total += building_count_in_area(type, minx, miny, maxx, maxy); + } + return total; +} + +int building_set_count_farms(int active_only) +{ + return count_all_types_in_set(active_only, building_set_farms, BUILDING_SET_SIZE_FARMS); +} + +int building_set_count_raw_materials(int active_only) +{ + return count_all_types_in_set(active_only, building_set_raw_materials, BUILDING_SET_SIZE_RAW_MATERIALS); +} + +int building_set_count_workshops(int active_only) +{ + return count_all_types_in_set(active_only, building_set_workshops, BUILDING_SET_SIZE_WORKSHOPS); +} + +int building_set_count_small_temples(int active_only) +{ + return count_all_types_in_set(active_only, building_set_small_temples, BUILDING_SET_SIZE_SMALL_TEMPLES); +} + +int building_set_count_large_temples(int active_only) +{ + return count_all_types_in_set(active_only, building_set_large_temples, BUILDING_SET_SIZE_LARGE_TEMPLES); +} + +int building_set_count_deco_trees(void) +{ + return count_all_types_in_set(0, building_set_deco_trees, BUILDING_SET_SIZE_DECO_TREES); +} + +int building_set_count_deco_paths(void) +{ + return count_all_types_in_set(0, building_set_deco_paths, BUILDING_SET_SIZE_DECO_PATHS); +} + +int building_set_count_deco_statues(void) +{ + return count_all_types_in_set(0, building_set_deco_statues, BUILDING_SET_SIZE_DECO_STATUES); +} + +int building_set_area_count_farms(int minx, int miny, int maxx, int maxy) +{ + return count_all_types_in_set_in_area(building_set_farms, BUILDING_SET_SIZE_FARMS, minx, miny, maxx, maxy); +} + +int building_set_area_count_raw_materials(int minx, int miny, int maxx, int maxy) +{ + return count_all_types_in_set_in_area(building_set_raw_materials, BUILDING_SET_SIZE_RAW_MATERIALS, minx, miny, maxx, maxy); +} + +int building_set_area_count_workshops(int minx, int miny, int maxx, int maxy) +{ + return count_all_types_in_set_in_area(building_set_workshops, BUILDING_SET_SIZE_WORKSHOPS, minx, miny, maxx, maxy); +} + +int building_set_area_count_small_temples(int minx, int miny, int maxx, int maxy) +{ + return count_all_types_in_set_in_area(building_set_small_temples, BUILDING_SET_SIZE_SMALL_TEMPLES, minx, miny, maxx, maxy); +} + +int building_set_area_count_large_temples(int minx, int miny, int maxx, int maxy) +{ + return count_all_types_in_set_in_area(building_set_large_temples, BUILDING_SET_SIZE_LARGE_TEMPLES, minx, miny, maxx, maxy); +} + +int building_set_area_count_grand_temples(int minx, int miny, int maxx, int maxy) +{ + return count_all_types_in_set_in_area(building_set_grand_temples, BUILDING_SET_SIZE_GRAND_TEMPLES, minx, miny, maxx, maxy); +} + +int building_set_area_count_deco_trees(int minx, int miny, int maxx, int maxy) +{ + return count_all_types_in_set_in_area(building_set_deco_trees, BUILDING_SET_SIZE_DECO_TREES, minx, miny, maxx, maxy); +} + +int building_set_area_count_deco_paths(int minx, int miny, int maxx, int maxy) +{ + return count_all_types_in_set_in_area(building_set_deco_paths, BUILDING_SET_SIZE_DECO_PATHS, minx, miny, maxx, maxy); +} + +int building_set_area_count_deco_statues(int minx, int miny, int maxx, int maxy) +{ + return count_all_types_in_set_in_area(building_set_deco_statues, BUILDING_SET_SIZE_DECO_STATUES, minx, miny, maxx, maxy); +} + + int building_count_active_fort_type(figure_type type) { int active = 0; diff --git a/src/building/count.h b/src/building/count.h index 4c3e3fdec6..e6d9cc41cc 100644 --- a/src/building/count.h +++ b/src/building/count.h @@ -25,6 +25,13 @@ int building_count_active(building_type type); */ int building_count_total(building_type type); +/** + * Returns the building count of all building types + * @param active_only Only count the building if it is active + * @return Total number of buildings + */ +int building_count_any_total(int active_only); + /** * Returns the upgraded building count for the type * @param type Building type @@ -42,9 +49,67 @@ int building_count_grand_temples(void); * Returns the total number of active grand temples * @return Number of active grand temples */ -int building_count_grand_temples(void); int building_count_grand_temples_active(void); +/** + * Returns the building count for the type in the given area + * @param type Building type + * @param minx Minimum x-axis value of the area to count in + * @param miny Minimum y-axis value of the area to count in + * @param maxx Maximum x-axis value of the area to count in + * @param maxy Maximum y-axis value of the area to count in + * @return Total number of buildings + */ +int building_count_in_area(building_type type, int minx, int miny, int maxx, int maxy); + +/** + * Returns the building count for any type in the given area + * @param minx Minimum x-axis value of the area to count in + * @param miny Minimum y-axis value of the area to count in + * @param maxx Maximum x-axis value of the area to count in + * @param maxy Maximum y-axis value of the area to count in + * @param type Figure type + * @return Total number of buildings + */ +int building_count_fort_type_in_area(int minx, int miny, int maxx, int maxy, figure_type type); + +/** + * Returns the total number of buildings (where the type is from the set of buildings) + * @param active_only Only count the building if it is active + * @return Number of buildings + */ +int building_set_count_farms(int active_only); +int building_set_count_raw_materials(int active_only); +int building_set_count_workshops(int active_only); +int building_set_count_small_temples(int active_only); +int building_set_count_large_temples(int active_only); + +/** + * Returns the total number of buildings (where the type is from the set of buildings) + * @return Number of buildings + */ +int building_set_count_deco_trees(void); +int building_set_count_deco_paths(void); +int building_set_count_deco_statues(void); + +/** + * Returns the total number of buildings (where the type is from the set of buildings) in the given area + * @param minx Minimum x-axis value of the area to count in + * @param miny Minimum y-axis value of the area to count in + * @param maxx Maximum x-axis value of the area to count in + * @param maxy Maximum y-axis value of the area to count in + * @return Number of buildings + */ +int building_set_area_count_farms(int minx, int miny, int maxx, int maxy); +int building_set_area_count_raw_materials(int minx, int miny, int maxx, int maxy); +int building_set_area_count_workshops(int minx, int miny, int maxx, int maxy); +int building_set_area_count_small_temples(int minx, int miny, int maxx, int maxy); +int building_set_area_count_large_temples(int minx, int miny, int maxx, int maxy); +int building_set_area_count_grand_temples(int minx, int miny, int maxx, int maxy); +int building_set_area_count_deco_trees(int minx, int miny, int maxx, int maxy); +int building_set_area_count_deco_paths(int minx, int miny, int maxx, int maxy); +int building_set_area_count_deco_statues(int minx, int miny, int maxx, int maxy); + /** * Returns the active building count for forts based on the assigned soldier (figure) type * @param type Figure type diff --git a/src/building/type.h b/src/building/type.h index 6fca2b2a24..e51fa6b4a8 100644 --- a/src/building/type.h +++ b/src/building/type.h @@ -10,6 +10,7 @@ * Building types */ typedef enum { + BUILDING_ANY = 0, BUILDING_NONE = 0, BUILDING_MENU_FARMS = 2, BUILDING_MENU_RAW_MATERIALS = 3, diff --git a/src/scenario/condition_types/condition_handler.c b/src/scenario/condition_types/condition_handler.c index c8866fbf2b..5c43f68390 100644 --- a/src/scenario/condition_types/condition_handler.c +++ b/src/scenario/condition_types/condition_handler.c @@ -21,6 +21,8 @@ int scenario_condition_type_is_met(scenario_condition_t *condition) return scenario_condition_type_building_count_active_met(condition); case CONDITION_TYPE_BUILDING_COUNT_ANY: return scenario_condition_type_building_count_any_met(condition); + case CONDITION_TYPE_BUILDING_COUNT_AREA: + return scenario_condition_type_building_count_area_met(condition); case CONDITION_TYPE_CITY_POPULATION: return scenario_condition_type_city_population_met(condition); case CONDITION_TYPE_COUNT_OWN_TROOPS: diff --git a/src/scenario/condition_types/condition_types.c b/src/scenario/condition_types/condition_types.c index 9211677a8d..79806ad117 100644 --- a/src/scenario/condition_types/condition_types.c +++ b/src/scenario/condition_types/condition_types.c @@ -15,6 +15,7 @@ #include "empire/trade_route.h" #include "game/settings.h" #include "game/time.h" +#include "map/grid.h" #include "scenario/request.h" #include "scenario/scenario.h" #include "scenario/condition_types/comparison_helper.h" @@ -28,87 +29,34 @@ int scenario_condition_type_building_count_active_met(const scenario_condition_t int total_active_count = 0; switch(type) { case BUILDING_MENU_FARMS: - total_active_count += building_count_active(BUILDING_WHEAT_FARM); - total_active_count += building_count_active(BUILDING_VEGETABLE_FARM); - total_active_count += building_count_active(BUILDING_FRUIT_FARM); - total_active_count += building_count_active(BUILDING_OLIVE_FARM); - total_active_count += building_count_active(BUILDING_VINES_FARM); - total_active_count += building_count_active(BUILDING_PIG_FARM); + total_active_count = building_set_count_farms(1); break; case BUILDING_MENU_RAW_MATERIALS: - total_active_count += building_count_active(BUILDING_MARBLE_QUARRY); - total_active_count += building_count_active(BUILDING_IRON_MINE); - total_active_count += building_count_active(BUILDING_TIMBER_YARD); - total_active_count += building_count_active(BUILDING_CLAY_PIT); - total_active_count += building_count_active(BUILDING_GOLD_MINE); - total_active_count += building_count_active(BUILDING_STONE_QUARRY); - total_active_count += building_count_active(BUILDING_SAND_PIT); + total_active_count = building_set_count_raw_materials(1); break; case BUILDING_MENU_WORKSHOPS: - total_active_count += building_count_active(BUILDING_WINE_WORKSHOP); - total_active_count += building_count_active(BUILDING_OIL_WORKSHOP); - total_active_count += building_count_active(BUILDING_WEAPONS_WORKSHOP); - total_active_count += building_count_active(BUILDING_FURNITURE_WORKSHOP); - total_active_count += building_count_active(BUILDING_POTTERY_WORKSHOP); - total_active_count += building_count_active(BUILDING_CONCRETE_MAKER); - total_active_count += building_count_active(BUILDING_BRICKWORKS); - total_active_count += building_count_active(BUILDING_CITY_MINT); + total_active_count = building_set_count_workshops(1); break; case BUILDING_MENU_SMALL_TEMPLES: - total_active_count += building_count_active(BUILDING_SMALL_TEMPLE_CERES); - total_active_count += building_count_active(BUILDING_SMALL_TEMPLE_NEPTUNE); - total_active_count += building_count_active(BUILDING_SMALL_TEMPLE_MERCURY); - total_active_count += building_count_active(BUILDING_SMALL_TEMPLE_MARS); - total_active_count += building_count_active(BUILDING_SMALL_TEMPLE_VENUS); + total_active_count = building_set_count_small_temples(1); break; case BUILDING_MENU_LARGE_TEMPLES: - total_active_count += building_count_active(BUILDING_LARGE_TEMPLE_CERES); - total_active_count += building_count_active(BUILDING_LARGE_TEMPLE_NEPTUNE); - total_active_count += building_count_active(BUILDING_LARGE_TEMPLE_MERCURY); - total_active_count += building_count_active(BUILDING_LARGE_TEMPLE_MARS); - total_active_count += building_count_active(BUILDING_LARGE_TEMPLE_VENUS); + total_active_count = building_set_count_large_temples(1); break; case BUILDING_MENU_GRAND_TEMPLES: - total_active_count += building_count_active(BUILDING_GRAND_TEMPLE_CERES); - total_active_count += building_count_active(BUILDING_GRAND_TEMPLE_NEPTUNE); - total_active_count += building_count_active(BUILDING_GRAND_TEMPLE_MERCURY); - total_active_count += building_count_active(BUILDING_GRAND_TEMPLE_MARS); - total_active_count += building_count_active(BUILDING_GRAND_TEMPLE_VENUS); + total_active_count = building_count_grand_temples_active(); break; case BUILDING_MENU_TREES: - total_active_count += building_count_active(BUILDING_PINE_TREE); - total_active_count += building_count_active(BUILDING_FIR_TREE); - total_active_count += building_count_active(BUILDING_OAK_TREE); - total_active_count += building_count_active(BUILDING_ELM_TREE); - total_active_count += building_count_active(BUILDING_FIG_TREE); - total_active_count += building_count_active(BUILDING_PLUM_TREE); - total_active_count += building_count_active(BUILDING_PALM_TREE); - total_active_count += building_count_active(BUILDING_DATE_TREE); + total_active_count = building_set_count_deco_trees(); break; case BUILDING_MENU_PATHS: - total_active_count += building_count_active(BUILDING_PINE_PATH); - total_active_count += building_count_active(BUILDING_FIR_PATH); - total_active_count += building_count_active(BUILDING_OAK_PATH); - total_active_count += building_count_active(BUILDING_ELM_PATH); - total_active_count += building_count_active(BUILDING_FIG_PATH); - total_active_count += building_count_active(BUILDING_PLUM_PATH); - total_active_count += building_count_active(BUILDING_PALM_PATH); - total_active_count += building_count_active(BUILDING_DATE_PATH); - total_active_count += building_count_active(BUILDING_GARDEN_PATH); + total_active_count = building_set_count_deco_paths(); break; case BUILDING_MENU_PARKS: - total_active_count += building_count_active(BUILDING_GARDENS); - total_active_count += building_count_active(BUILDING_GRAND_GARDEN); - total_active_count += building_count_active(BUILDING_SMALL_STATUE); - total_active_count += building_count_active(BUILDING_MEDIUM_STATUE); - total_active_count += building_count_active(BUILDING_LARGE_STATUE); - total_active_count += building_count_active(BUILDING_SMALL_STATUE_ALT); - total_active_count += building_count_active(BUILDING_SMALL_STATUE_ALT_B); - total_active_count += building_count_active(BUILDING_LEGION_STATUE); - total_active_count += building_count_active(BUILDING_GLADIATOR_STATUE); - total_active_count += building_count_active(BUILDING_SMALL_POND); - total_active_count += building_count_active(BUILDING_LARGE_POND); - total_active_count += building_count_active(BUILDING_DOLPHIN_FOUNTAIN); + total_active_count = building_set_count_deco_statues(); + break; + case BUILDING_ANY: + total_active_count = building_count_any_total(1); break; case BUILDING_FORT_LEGIONARIES: total_active_count += building_count_fort_type_total(FIGURE_FORT_LEGIONARY); @@ -120,7 +68,7 @@ int scenario_condition_type_building_count_active_met(const scenario_condition_t total_active_count += building_count_fort_type_total(FIGURE_FORT_MOUNTED); break; default: - total_active_count += building_count_active(type); + total_active_count = building_count_active(type); break; } @@ -136,83 +84,34 @@ int scenario_condition_type_building_count_any_met(const scenario_condition_t *c int total_active_count = 0; switch(type) { case BUILDING_MENU_FARMS: - total_active_count += building_count_total(BUILDING_WHEAT_FARM); - total_active_count += building_count_total(BUILDING_VEGETABLE_FARM); - total_active_count += building_count_total(BUILDING_FRUIT_FARM); - total_active_count += building_count_total(BUILDING_OLIVE_FARM); - total_active_count += building_count_total(BUILDING_VINES_FARM); - total_active_count += building_count_total(BUILDING_PIG_FARM); + total_active_count = building_set_count_farms(0); break; case BUILDING_MENU_RAW_MATERIALS: - total_active_count += building_count_total(BUILDING_MARBLE_QUARRY); - total_active_count += building_count_total(BUILDING_IRON_MINE); - total_active_count += building_count_total(BUILDING_TIMBER_YARD); - total_active_count += building_count_total(BUILDING_CLAY_PIT); - total_active_count += building_count_total(BUILDING_GOLD_MINE); + total_active_count = building_set_count_raw_materials(0); break; case BUILDING_MENU_WORKSHOPS: - total_active_count += building_count_total(BUILDING_WINE_WORKSHOP); - total_active_count += building_count_total(BUILDING_OIL_WORKSHOP); - total_active_count += building_count_total(BUILDING_WEAPONS_WORKSHOP); - total_active_count += building_count_total(BUILDING_FURNITURE_WORKSHOP); - total_active_count += building_count_total(BUILDING_POTTERY_WORKSHOP); - total_active_count += building_count_total(BUILDING_CITY_MINT); + total_active_count = building_set_count_workshops(0); break; case BUILDING_MENU_SMALL_TEMPLES: - total_active_count += building_count_total(BUILDING_SMALL_TEMPLE_CERES); - total_active_count += building_count_total(BUILDING_SMALL_TEMPLE_NEPTUNE); - total_active_count += building_count_total(BUILDING_SMALL_TEMPLE_MERCURY); - total_active_count += building_count_total(BUILDING_SMALL_TEMPLE_MARS); - total_active_count += building_count_total(BUILDING_SMALL_TEMPLE_VENUS); + total_active_count = building_set_count_small_temples(0); break; case BUILDING_MENU_LARGE_TEMPLES: - total_active_count += building_count_total(BUILDING_LARGE_TEMPLE_CERES); - total_active_count += building_count_total(BUILDING_LARGE_TEMPLE_NEPTUNE); - total_active_count += building_count_total(BUILDING_LARGE_TEMPLE_MERCURY); - total_active_count += building_count_total(BUILDING_LARGE_TEMPLE_MARS); - total_active_count += building_count_total(BUILDING_LARGE_TEMPLE_VENUS); + total_active_count = building_set_count_large_temples(0); break; case BUILDING_MENU_GRAND_TEMPLES: - total_active_count += building_count_total(BUILDING_GRAND_TEMPLE_CERES); - total_active_count += building_count_total(BUILDING_GRAND_TEMPLE_NEPTUNE); - total_active_count += building_count_total(BUILDING_GRAND_TEMPLE_MERCURY); - total_active_count += building_count_total(BUILDING_GRAND_TEMPLE_MARS); - total_active_count += building_count_total(BUILDING_GRAND_TEMPLE_VENUS); + total_active_count = building_count_grand_temples(); break; case BUILDING_MENU_TREES: - total_active_count += building_count_total(BUILDING_PINE_TREE); - total_active_count += building_count_total(BUILDING_FIR_TREE); - total_active_count += building_count_total(BUILDING_OAK_TREE); - total_active_count += building_count_total(BUILDING_ELM_TREE); - total_active_count += building_count_total(BUILDING_FIG_TREE); - total_active_count += building_count_total(BUILDING_PLUM_TREE); - total_active_count += building_count_total(BUILDING_PALM_TREE); - total_active_count += building_count_total(BUILDING_DATE_TREE); + total_active_count = building_set_count_deco_trees(); break; case BUILDING_MENU_PATHS: - total_active_count += building_count_total(BUILDING_PINE_PATH); - total_active_count += building_count_total(BUILDING_FIR_PATH); - total_active_count += building_count_total(BUILDING_OAK_PATH); - total_active_count += building_count_total(BUILDING_ELM_PATH); - total_active_count += building_count_total(BUILDING_FIG_PATH); - total_active_count += building_count_total(BUILDING_PLUM_PATH); - total_active_count += building_count_total(BUILDING_PALM_PATH); - total_active_count += building_count_total(BUILDING_DATE_PATH); - total_active_count += building_count_total(BUILDING_GARDEN_PATH); + total_active_count = building_set_count_deco_paths(); break; case BUILDING_MENU_PARKS: - total_active_count += building_count_total(BUILDING_GARDENS); - total_active_count += building_count_total(BUILDING_GRAND_GARDEN); - total_active_count += building_count_total(BUILDING_SMALL_STATUE); - total_active_count += building_count_total(BUILDING_MEDIUM_STATUE); - total_active_count += building_count_total(BUILDING_LARGE_STATUE); - total_active_count += building_count_total(BUILDING_SMALL_STATUE_ALT); - total_active_count += building_count_total(BUILDING_SMALL_STATUE_ALT_B); - total_active_count += building_count_total(BUILDING_LEGION_STATUE); - total_active_count += building_count_total(BUILDING_GLADIATOR_STATUE); - total_active_count += building_count_total(BUILDING_SMALL_POND); - total_active_count += building_count_total(BUILDING_LARGE_POND); - total_active_count += building_count_total(BUILDING_DOLPHIN_FOUNTAIN); + total_active_count = building_set_count_deco_statues(); + break; + case BUILDING_ANY: + total_active_count = building_count_any_total(0); break; case BUILDING_FORT_LEGIONARIES: total_active_count += building_count_fort_type_total(FIGURE_FORT_LEGIONARY); @@ -224,13 +123,75 @@ int scenario_condition_type_building_count_any_met(const scenario_condition_t *c total_active_count += building_count_fort_type_total(FIGURE_FORT_MOUNTED); break; default: - total_active_count += building_count_total(type); + total_active_count = building_count_total(type); break; } return comparison_helper_compare_values(comparison, total_active_count, value); } +int scenario_condition_type_building_count_area_met(const scenario_condition_t *condition) +{ + int grid_offset = condition->parameter1; + int block_radius = condition->parameter2; + building_type type = condition->parameter3; + int comparison = condition->parameter4; + int value = condition->parameter5; + + if (!map_grid_is_valid_offset(grid_offset)) { + return 0; + } + + int minx = map_grid_offset_to_x(grid_offset) - block_radius; + int miny = map_grid_offset_to_y(grid_offset) - block_radius; + int maxx = map_grid_offset_to_x(grid_offset) + block_radius; + int maxy = map_grid_offset_to_y(grid_offset) + block_radius; + int buildings_in_area = 0; + switch(type) { + case BUILDING_MENU_FARMS: + buildings_in_area = building_set_area_count_farms(minx, miny, maxx, maxy); + break; + case BUILDING_MENU_RAW_MATERIALS: + buildings_in_area = building_set_area_count_raw_materials(minx, miny, maxx, maxy); + break; + case BUILDING_MENU_WORKSHOPS: + buildings_in_area = building_set_area_count_workshops(minx, miny, maxx, maxy); + break; + case BUILDING_MENU_SMALL_TEMPLES: + buildings_in_area = building_set_area_count_small_temples(minx, miny, maxx, maxy); + break; + case BUILDING_MENU_LARGE_TEMPLES: + buildings_in_area = building_set_area_count_large_temples(minx, miny, maxx, maxy); + break; + case BUILDING_MENU_GRAND_TEMPLES: + buildings_in_area = building_set_area_count_grand_temples(minx, miny, maxx, maxy); + break; + case BUILDING_MENU_TREES: + buildings_in_area = building_set_area_count_deco_trees(minx, miny, maxx, maxy); + break; + case BUILDING_MENU_PATHS: + buildings_in_area = building_set_area_count_deco_paths(minx, miny, maxx, maxy); + break; + case BUILDING_MENU_PARKS: + buildings_in_area = building_set_area_count_deco_statues(minx, miny, maxx, maxy); + break; + case BUILDING_FORT_LEGIONARIES: + buildings_in_area = building_count_fort_type_in_area(minx, miny, maxx, maxy, FIGURE_FORT_LEGIONARY); + break; + case BUILDING_FORT_JAVELIN: + buildings_in_area = building_count_fort_type_in_area(minx, miny, maxx, maxy, FIGURE_FORT_JAVELIN); + break; + case BUILDING_FORT_MOUNTED: + buildings_in_area = building_count_fort_type_in_area(minx, miny, maxx, maxy, FIGURE_FORT_MOUNTED); + break; + default: + buildings_in_area = building_count_in_area(type, minx, miny, maxx, maxy); + break; + } + + return comparison_helper_compare_values(comparison, buildings_in_area, value); +} + int scenario_condition_type_city_population_met(const scenario_condition_t *condition) { int comparison = condition->parameter1; diff --git a/src/scenario/condition_types/condition_types.h b/src/scenario/condition_types/condition_types.h index 2ceaee908b..cf42711d75 100644 --- a/src/scenario/condition_types/condition_types.h +++ b/src/scenario/condition_types/condition_types.h @@ -7,6 +7,8 @@ int scenario_condition_type_building_count_active_met(const scenario_condition_t int scenario_condition_type_building_count_any_met(const scenario_condition_t *condition); +int scenario_condition_type_building_count_area_met(const scenario_condition_t *condition); + int scenario_condition_type_city_population_met(const scenario_condition_t *condition); int scenario_condition_type_count_own_troops_met(const scenario_condition_t *condition); diff --git a/src/scenario/scenario_event_data.h b/src/scenario/scenario_event_data.h index c3312e61a3..a18ab8d13a 100644 --- a/src/scenario/scenario_event_data.h +++ b/src/scenario/scenario_event_data.h @@ -42,6 +42,7 @@ typedef enum { CONDITION_TYPE_TRADE_ROUTE_PRICE = 21, CONDITION_TYPE_RESOURCE_STORED_COUNT = 22, CONDITION_TYPE_RESOURCE_STORAGE_AVAILABLE = 23, + CONDITION_TYPE_BUILDING_COUNT_AREA = 24, CONDITION_TYPE_MAX, // helper constants CONDITION_TYPE_MIN = CONDITION_TYPE_TIME_PASSED, diff --git a/src/scenario/scenario_events_parameter_data.c b/src/scenario/scenario_events_parameter_data.c index f59e70ba3e..26814d0851 100644 --- a/src/scenario/scenario_events_parameter_data.c +++ b/src/scenario/scenario_events_parameter_data.c @@ -121,6 +121,13 @@ static scenario_condition_data_t scenario_condition_data[CONDITION_TYPE_MAX] = { .xml_parm3 = { .name = "value", .type = PARAMETER_TYPE_NUMBER, .min_limit = 0, .max_limit = UNLIMITED, .key = TR_PARAMETER_TYPE_NUMBER }, .xml_parm4 = { .name = "storage_type", .type = PARAMETER_TYPE_STORAGE_TYPE, .key = TR_PARAMETER_TYPE_STORAGE_TYPE }, .xml_parm5 = { .name = "respect_settings", .type = PARAMETER_TYPE_BOOLEAN, .min_limit = 0, .max_limit = 1, .key = TR_PARAMETER_RESPECT_SETTINGS }, }, + [CONDITION_TYPE_BUILDING_COUNT_AREA] = { .type = CONDITION_TYPE_BUILDING_COUNT_AREA, + .xml_attr = { .name = "building_count_area", .type = PARAMETER_TYPE_TEXT, .key = TR_CONDITION_TYPE_BUILDING_COUNT_AREA }, + .xml_parm1 = { .name = "grid_offset", .type = PARAMETER_TYPE_NUMBER, .min_limit = 0, .max_limit = UNLIMITED, .key = TR_PARAMETER_GRID_OFFSET }, + .xml_parm2 = { .name = "block_radius", .type = PARAMETER_TYPE_NUMBER, .min_limit = 0, .max_limit = UNLIMITED, .key = TR_PARAMETER_RADIUS }, + .xml_parm3 = { .name = "building", .type = PARAMETER_TYPE_BUILDING, .key = TR_PARAMETER_TYPE_BUILDING_COUNTING }, + .xml_parm4 = { .name = "check", .type = PARAMETER_TYPE_CHECK, .min_limit = 1, .max_limit = 6, .key = TR_PARAMETER_TYPE_CHECK }, + .xml_parm5 = { .name = "value", .type = PARAMETER_TYPE_NUMBER, .min_limit = 0, .max_limit = UNLIMITED, .key = TR_PARAMETER_TYPE_NUMBER }, }, }; scenario_condition_data_t *scenario_events_parameter_data_get_conditions_xml_attributes(condition_types type) @@ -350,12 +357,13 @@ static special_attribute_mapping_t special_attribute_mappings_pop_class[] = { #define SPECIAL_ATTRIBUTE_MAPPINGS_POP_CLASS_SIZE (sizeof(special_attribute_mappings_pop_class) / sizeof(special_attribute_mapping_t)) static special_attribute_mapping_t special_attribute_mappings_buildings[] = { - { .type = PARAMETER_TYPE_BUILDING, .text = "vacant_lot", .value = BUILDING_HOUSE_VACANT_LOT, .key = TR_PARAMETER_VALUE_DYNAMIC_RESOLVE }, - { .type = PARAMETER_TYPE_BUILDING, .text = "all_farms", .value = BUILDING_MENU_FARMS, .key = TR_PARAMETER_VALUE_BUILDING_MENU_FARMS }, - { .type = PARAMETER_TYPE_BUILDING, .text = "all_raw_materials", .value = BUILDING_MENU_RAW_MATERIALS, .key = TR_PARAMETER_VALUE_BUILDING_MENU_RAW_MATERIALS }, - { .type = PARAMETER_TYPE_BUILDING, .text = "all_workshops", .value = BUILDING_MENU_WORKSHOPS, .key = TR_PARAMETER_VALUE_BUILDING_MENU_WORKSHOPS }, - { .type = PARAMETER_TYPE_BUILDING, .text = "road", .value = BUILDING_ROAD, .key = TR_PARAMETER_VALUE_DYNAMIC_RESOLVE }, - { .type = PARAMETER_TYPE_BUILDING, .text = "wall", .value = BUILDING_WALL, .key = TR_PARAMETER_VALUE_DYNAMIC_RESOLVE }, + { .type = PARAMETER_TYPE_BUILDING, .text = "any", .value = BUILDING_ANY, .key = TR_PARAMETER_VALUE_BUILDING_ANY }, + { .type = PARAMETER_TYPE_BUILDING, .text = "vacant_lot", .value = BUILDING_HOUSE_VACANT_LOT, .key = TR_PARAMETER_VALUE_DYNAMIC_RESOLVE }, + { .type = PARAMETER_TYPE_BUILDING, .text = "all_farms", .value = BUILDING_MENU_FARMS, .key = TR_PARAMETER_VALUE_BUILDING_MENU_FARMS }, + { .type = PARAMETER_TYPE_BUILDING, .text = "all_raw_materials", .value = BUILDING_MENU_RAW_MATERIALS, .key = TR_PARAMETER_VALUE_BUILDING_MENU_RAW_MATERIALS }, + { .type = PARAMETER_TYPE_BUILDING, .text = "all_workshops", .value = BUILDING_MENU_WORKSHOPS, .key = TR_PARAMETER_VALUE_BUILDING_MENU_WORKSHOPS }, + { .type = PARAMETER_TYPE_BUILDING, .text = "road", .value = BUILDING_ROAD, .key = TR_PARAMETER_VALUE_DYNAMIC_RESOLVE }, + { .type = PARAMETER_TYPE_BUILDING, .text = "wall", .value = BUILDING_WALL, .key = TR_PARAMETER_VALUE_DYNAMIC_RESOLVE }, { .type = PARAMETER_TYPE_BUILDING, .text = "aqueduct", .value = BUILDING_AQUEDUCT, .key = TR_PARAMETER_VALUE_DYNAMIC_RESOLVE }, { .type = PARAMETER_TYPE_BUILDING, .text = "house_small_tent", .value = BUILDING_HOUSE_SMALL_TENT, .key = TR_PARAMETER_VALUE_DYNAMIC_RESOLVE }, { .type = PARAMETER_TYPE_BUILDING, .text = "house_large_tent", .value = BUILDING_HOUSE_LARGE_TENT, .key = TR_PARAMETER_VALUE_DYNAMIC_RESOLVE }, @@ -1057,8 +1065,10 @@ void scenario_events_parameter_data_get_display_string_for_action(scenario_actio } case ACTION_TYPE_BUILDING_FORCE_COLLAPSE: { + result_text = append_text(string_from_ascii(" "), result_text, &maxlength); result_text = append_text(translation_for(TR_PARAMETER_GRID_OFFSET), result_text, &maxlength); result_text = translation_for_number_value(action->parameter1, result_text, &maxlength); + result_text = append_text(string_from_ascii(" "), result_text, &maxlength); result_text = append_text(translation_for(TR_PARAMETER_RADIUS), result_text, &maxlength); result_text = translation_for_number_value(action->parameter2, result_text, &maxlength); if (action->parameter4) { @@ -1295,6 +1305,19 @@ void scenario_events_parameter_data_get_display_string_for_condition(scenario_co result_text = translation_for_boolean_text(condition->parameter2, TR_PARAMETER_DISPLAY_ONGOING, TR_PARAMETER_DISPLAY_NOT_ONGOING, result_text, &maxlength); return; } + case CONDITION_TYPE_BUILDING_COUNT_AREA: + { + result_text = append_text(string_from_ascii(" "), result_text, &maxlength); + result_text = append_text(translation_for(TR_PARAMETER_GRID_OFFSET), result_text, &maxlength); + result_text = translation_for_number_value(condition->parameter1, result_text, &maxlength); + result_text = append_text(string_from_ascii(" "), result_text, &maxlength); + result_text = append_text(translation_for(TR_PARAMETER_RADIUS), result_text, &maxlength); + result_text = translation_for_number_value(condition->parameter2, result_text, &maxlength); + result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_BUILDING, condition->parameter3, result_text, &maxlength); + result_text = translation_for_attr_mapping_text(xml_info->xml_parm4.type, condition->parameter4, result_text, &maxlength); + result_text = translation_for_number_value(condition->parameter5, result_text, &maxlength); + return; + } case CONDITION_TYPE_RESOURCE_STORAGE_AVAILABLE: { result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_STORAGE_TYPE, condition->parameter4, result_text, &maxlength); diff --git a/src/translation/english.c b/src/translation/english.c index 7a790f2ebe..ed4b940075 100644 --- a/src/translation/english.c +++ b/src/translation/english.c @@ -1108,6 +1108,7 @@ static translation_string all_strings[] = { {TR_CONDITION_TYPE_TRADE_ROUTE_PRICE, "Trade route open price"}, {TR_CONDITION_TYPE_RESOURCE_STORED_COUNT, "Resource stored count"}, {TR_CONDITION_TYPE_RESOURCE_STORAGE_AVAILABLE, "Resource storage available"}, + {TR_CONDITION_TYPE_BUILDING_COUNT_AREA, "Buildings in area"}, {TR_ACTION_TYPE_ADJUST_FAVOR, "Adjust favor"}, {TR_ACTION_TYPE_ADJUST_MONEY, "Adjust money"}, {TR_ACTION_TYPE_ADJUST_SAVINGS, "Adjust savings"}, @@ -1155,6 +1156,7 @@ static translation_string all_strings[] = { {TR_PARAMETER_VALUE_POP_CLASS_PLEBEIAN, "Plebeians"}, {TR_PARAMETER_VALUE_POP_CLASS_SLUMS, "Slumdwellers"}, {TR_PARAMETER_VALUE_BUILDING_NONE, "None"}, + {TR_PARAMETER_VALUE_BUILDING_ANY, "Any"}, {TR_PARAMETER_VALUE_BUILDING_MENU_FARMS, "All farms"}, {TR_PARAMETER_VALUE_BUILDING_MENU_RAW_MATERIALS, "All raw materials"}, {TR_PARAMETER_VALUE_BUILDING_MENU_WORKSHOPS, "All workshops"}, diff --git a/src/translation/translation.h b/src/translation/translation.h index ff13a89cce..8c23aceaa9 100644 --- a/src/translation/translation.h +++ b/src/translation/translation.h @@ -1102,6 +1102,7 @@ typedef enum { TR_CONDITION_TYPE_TRADE_ROUTE_PRICE, TR_CONDITION_TYPE_RESOURCE_STORED_COUNT, TR_CONDITION_TYPE_RESOURCE_STORAGE_AVAILABLE, + TR_CONDITION_TYPE_BUILDING_COUNT_AREA, TR_ACTION_TYPE_ADJUST_FAVOR, TR_ACTION_TYPE_ADJUST_MONEY, TR_ACTION_TYPE_ADJUST_SAVINGS, @@ -1149,6 +1150,7 @@ typedef enum { TR_PARAMETER_VALUE_POP_CLASS_PLEBEIAN, TR_PARAMETER_VALUE_POP_CLASS_SLUMS, TR_PARAMETER_VALUE_BUILDING_NONE, + TR_PARAMETER_VALUE_BUILDING_ANY, TR_PARAMETER_VALUE_BUILDING_MENU_FARMS, TR_PARAMETER_VALUE_BUILDING_MENU_RAW_MATERIALS, TR_PARAMETER_VALUE_BUILDING_MENU_WORKSHOPS,