diff --git a/CMakeLists.txt b/CMakeLists.txt index ab42393215..40f985bd6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -669,6 +669,7 @@ set(WINDOW_FILES ${PROJECT_SOURCE_DIR}/src/window/editor/invasions.c ${PROJECT_SOURCE_DIR}/src/window/editor/map.c ${PROJECT_SOURCE_DIR}/src/window/editor/model_data.c + ${PROJECT_SOURCE_DIR}/src/window/editor/house_model_data.c ${PROJECT_SOURCE_DIR}/src/window/editor/price_changes.c ${PROJECT_SOURCE_DIR}/src/window/editor/requests.c ${PROJECT_SOURCE_DIR}/src/window/editor/scenario_events.c diff --git a/res/assets/Graphics/UI/abstract_caret_symbol.png b/res/assets/Graphics/UI/abstract_caret_symbol.png new file mode 100644 index 0000000000..c21fd4f794 Binary files /dev/null and b/res/assets/Graphics/UI/abstract_caret_symbol.png differ diff --git a/res/assets/Graphics/ui.xml b/res/assets/Graphics/ui.xml index f431e868f1..6024885ab5 100644 --- a/res/assets/Graphics/ui.xml +++ b/res/assets/Graphics/ui.xml @@ -1419,13 +1419,14 @@ - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/assets.c b/src/assets/assets.c index b981a82d84..0c3f0c9fbc 100644 --- a/src/assets/assets.c +++ b/src/assets/assets.c @@ -85,6 +85,7 @@ void assets_init(int force_reload, color_t **main_images, int *main_image_widths data.font_lookup[ASSET_FONT_SQ_BRACKET_RIGHT] = assets_get_image_id("UI", "rightbracket_white_l"); data.font_lookup[ASSET_FONT_CRLY_BRACKET_LEFT] = assets_get_image_id("UI", "curlybracket_white_left"); data.font_lookup[ASSET_FONT_CRLY_BRACKET_RIGHT] = assets_get_image_id("UI", "curlybracket_white_right"); + data.font_lookup[ASSET_FONT_ABSTRACT_CARET_SYMBOL] = assets_get_image_id("UI", "abstract_caret_symbol"); } diff --git a/src/assets/assets.h b/src/assets/assets.h index 648ba6ef82..b3bf628948 100644 --- a/src/assets/assets.h +++ b/src/assets/assets.h @@ -49,6 +49,7 @@ typedef enum { ASSET_FONT_SQ_BRACKET_RIGHT, ASSET_FONT_CRLY_BRACKET_LEFT, ASSET_FONT_CRLY_BRACKET_RIGHT, + ASSET_FONT_ABSTRACT_CARET_SYMBOL, ASSET_FONT_MAX_KEY } asset_font_id; diff --git a/src/building/building.c b/src/building/building.c index f3d90278b5..680915e7ed 100644 --- a/src/building/building.c +++ b/src/building/building.c @@ -415,7 +415,7 @@ int building_repair_cost(building *b) if (building_is_house(og_type)) { grid_slice *house_slice = map_grid_get_grid_slice_house(b->id, 1); - int clear_cost = house_slice->size * (11 + 3); // 10.5 per new house tile + 3 per rubble tile to clear + int clear_cost = house_slice->size * (11 + model_get_building(BUILDING_REPAIR_LAND)->cost); // 10.5 per new house tile + cost of repair land per rubble tile to clear return clear_cost; } if (b->type == BUILDING_WAREHOUSE_SPACE) { diff --git a/src/building/construction_building.c b/src/building/construction_building.c index 583b279a88..da156e739b 100644 --- a/src/building/construction_building.c +++ b/src/building/construction_building.c @@ -92,7 +92,7 @@ int building_construction_prepare_terrain(grid_slice *grid_slice, clear_mode cle break; } if (map_terrain_is(g_offset, terrain_mask_to_remove)) { - total_cost += (cost == COST_FREE) ? 0 : 3; // base cost per tile is 50% more than regular clear + total_cost += (cost == COST_FREE) ? 0 : model_get_building(BUILDING_REPAIR_LAND)->cost; // base cost per tile is the cost of repair land if (cost != COST_MEASURE) { map_terrain_remove(g_offset, terrain_mask_to_remove); } diff --git a/src/building/construction_building.h b/src/building/construction_building.h index 55a2d1fee7..7c254f1a71 100644 --- a/src/building/construction_building.h +++ b/src/building/construction_building.h @@ -15,7 +15,7 @@ typedef enum { COST_FREE = -1, // perform operation for free COST_MEASURE = 0, // measure cost only, do not perform operation COST_PROCESS = 1 // perform operation for a cost -}cost_calculation; +} cost_calculation; /** * @brief Places a building of the specified type at the given coordinates * CAREFUL: x and y are offset depending on city orientation, can cause problems with exact coordinates given @@ -47,5 +47,3 @@ int building_construction_fill_vacant_lots(grid_slice *area); int building_construction_prepare_terrain(grid_slice *grid_slice, clear_mode clear_mode, cost_calculation cost); #endif // BUILDING_CONSTRUCTION_BUILDING_H - - diff --git a/src/building/figure.c b/src/building/figure.c index ac1e98971f..57f45f9ff6 100644 --- a/src/building/figure.c +++ b/src/building/figure.c @@ -1611,6 +1611,8 @@ static void spawn_figure_barracks(building *b) if (city_data.mess_hall.food_stress_cumulative > 20) { spawn_delay += city_data.mess_hall.food_stress_cumulative - 20; } + + spawn_delay = calc_adjust_with_percentage(spawn_delay, resource_get_data(RESOURCE_TROOPS)->production_per_month); b->figure_spawn_delay++; if (b->figure_spawn_delay > spawn_delay) { diff --git a/src/building/house_evolution.c b/src/building/house_evolution.c index 574c18a23b..6db7987738 100644 --- a/src/building/house_evolution.c +++ b/src/building/house_evolution.c @@ -65,18 +65,12 @@ static int has_required_goods_and_services(building *house, int for_upgrade, int // water int water = model->water; if (!house->has_water_access) { - if (water >= 2) { - if (level > HOUSE_SMALL_CASA) { - ++demands->missing.fountain; - return 0; - } else if (!house->has_well_access) { - ++demands->missing.well; - return 0; - } else if (level > HOUSE_LARGE_SHACK && !house->has_latrines_access) { - return 0; - } - } - if (water == 1 && !house->has_well_access) { + if (water > 2) { + ++demands->missing.fountain; + return 0; + } else if (water > 1 && !house->has_latrines_access) { + return 0; + } if (water == 1 && !house->has_well_access) { ++demands->missing.well; return 0; } @@ -628,9 +622,6 @@ void building_house_determine_evolve_text(building *house, int worst_desirabilit if (!house->has_well_access) { house->data.house.evolve_text_id = 1; return; - } else if (!house->has_latrines_access) { - house->data.house.evolve_text_id = 68; - return; } } @@ -638,11 +629,12 @@ void building_house_determine_evolve_text(building *house, int worst_desirabilit if (!house->has_latrines_access) { house->data.house.evolve_text_id = 67; return; - } else if (level >= HOUSE_LARGE_CASA) { - house->data.house.evolve_text_id = 2; - return; } } + + if (water == 3 && !house->has_water_access) { + house->data.house.evolve_text_id = 2; + } // entertainment int entertainment = model->entertainment; @@ -788,14 +780,18 @@ void building_house_determine_evolve_text(building *house, int worst_desirabilit if (!house->has_well_access) { house->data.house.evolve_text_id = 31; return; - } else if (!house->has_latrines_access) { - house->data.house.evolve_text_id = 68; - return; } } if (water == 2 && !house->has_water_access) { - if (level >= HOUSE_LARGE_CASA && house->has_well_access && house->has_latrines_access) { + if (!house->has_latrines_access || !house->has_well_access) { + house->data.house.evolve_text_id = 68; + return; + } + } + + if (water == 3 && !house->has_water_access) { + if (house->has_well_access && house->has_latrines_access) { house->data.house.evolve_text_id = 32; return; } diff --git a/src/building/properties.c b/src/building/properties.c index 1fc339e0b1..7fa33f53be 100644 --- a/src/building/properties.c +++ b/src/building/properties.c @@ -1,6 +1,7 @@ #include "properties.h" #include "assets/assets.h" +#include "building/building.h" #include "core/image_group.h" #include "sound/city.h" #include "translation/translation.h" @@ -9,7 +10,52 @@ #include #include +#define NUM_HOUSES 20 + +#define SIZE_BUILDINGS sizeof(model_building) * BUILDING_TYPE_MAX +#define SIZE_HOUSES sizeof(model_house) * NUM_HOUSES + +#define BUFFER_SIZE SIZE_BUILDINGS + SIZE_HOUSES + +#define UNLIMITED 1000000000 +#define NEGATIVE_UNLIMITED -1000000000 + static model_building buildings[BUILDING_TYPE_MAX]; +static model_house houses[NUM_HOUSES]; + +struct min_max { + int min; + int max; +}; + +static struct min_max min_max_for_data_types[MODEL_BUILDING_MAX] = { + [MODEL_COST] = {.min = NEGATIVE_UNLIMITED, .max = UNLIMITED}, + [MODEL_DESIRABILITY_VALUE] = {.min = -100, .max = 100}, + [MODEL_DESIRABILITY_STEP] = {.min = 0, .max = 8}, + [MODEL_DESIRABILITY_STEP_SIZE] = {.min = -100, .max = 100}, + [MODEL_DESIRABILITY_RANGE] = {.min = 0, .max = 8}, + [MODEL_LABORERS] = {.min = 0, .max = UNLIMITED} +}; + +static struct min_max min_max_for_house_data_types[MODEL_HOUSE_MAX] = { + [MODEL_DEVOLVE_DESIRABILITY] = {.min = -101, .max = 100}, + [MODEL_EVOLVE_DESIRABILITY] = {.min = -101, .max = 100}, + [MODEL_ENTERTAINMENT] = {.min = 0, .max = 116}, + [MODEL_WATER] = {.min = 0, .max = 3}, + [MODEL_RELIGION] = {.min = 0, .max = 5}, + [MODEL_EDUCATION] = {.min = 0, .max = 3}, + [MODEL_BARBER] = {.min = 0, .max = 1}, + [MODEL_BATHHOUSE] = {.min = 0, .max = 1}, + [MODEL_HEALTH] = {.min = 0, .max = 2}, + [MODEL_FOOD_TYPES] = {.min = 0, .max = 5}, + [MODEL_POTTERY] = {.min = 0, .max = 1}, + [MODEL_OIL] = {.min = 0, .max = 1}, + [MODEL_FURNITURE] = {.min = 0, .max = 1}, + [MODEL_WINE] = {.min = 0, .max = 2}, + [MODEL_PROSPERITY] = {.min = NEGATIVE_UNLIMITED, .max = UNLIMITED}, + [MODEL_MAX_PEOPLE] = {.min = 0, .max = UNLIMITED}, + [MODEL_TAX_MULTIPLIER] = {.min = NEGATIVE_UNLIMITED, .max = UNLIMITED} +}; // PROPERTIES @@ -260,7 +306,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .devolve_desirability = 14, .evolve_desirability = 20, .entertainment = 10, - .water = 2, + .water = 3, .religion = 1, .education = 1, .barber = 0, @@ -285,7 +331,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .devolve_desirability = 18, .evolve_desirability = 25, .entertainment = 25, - .water = 2, + .water = 3, .religion = 1, .education = 1, .barber = 0, @@ -310,7 +356,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .devolve_desirability = 22, .evolve_desirability = 32, .entertainment = 25, - .water = 2, + .water = 3, .religion = 1, .education = 1, .barber = 0, @@ -335,7 +381,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .devolve_desirability = 29, .evolve_desirability = 40, .entertainment = 25, - .water = 2, + .water = 3, .religion = 1, .education = 2, .barber = 1, @@ -360,7 +406,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .devolve_desirability = 37, .evolve_desirability = 48, .entertainment = 35, - .water = 2, + .water = 3, .religion = 1, .education = 2, .barber = 1, @@ -385,7 +431,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .devolve_desirability = 45, .evolve_desirability = 53, .entertainment = 35, - .water = 2, + .water = 3, .religion = 2, .education = 2, .barber = 1, @@ -410,7 +456,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .devolve_desirability = 50, .evolve_desirability = 58, .entertainment = 40, - .water = 2, + .water = 3, .religion = 2, .education = 2, .barber = 1, @@ -435,7 +481,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .devolve_desirability = 55, .evolve_desirability = 63, .entertainment = 45, - .water = 2, + .water = 3, .religion = 2, .education = 3, .barber = 1, @@ -460,7 +506,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .devolve_desirability = 60, .evolve_desirability = 68, .entertainment = 50, - .water = 2, + .water = 3, .religion = 3, .education = 3, .barber = 1, @@ -485,7 +531,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .devolve_desirability = 65, .evolve_desirability = 74, .entertainment = 55, - .water = 2, + .water = 3, .religion = 3, .education = 3, .barber = 1, @@ -510,7 +556,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .devolve_desirability = 70, .evolve_desirability = 80, .entertainment = 60, - .water = 2, + .water = 3, .religion = 4, .education = 3, .barber = 1, @@ -535,7 +581,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .devolve_desirability = 76, .evolve_desirability = 90, .entertainment = 70, - .water = 2, + .water = 3, .religion = 4, .education = 3, .barber = 1, @@ -560,7 +606,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .devolve_desirability = 85, .evolve_desirability = 100, .entertainment = 80, - .water = 2, + .water = 3, .religion = 4, .education = 3, .barber = 1, @@ -861,7 +907,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .event_data.attr = "small_temple_ceres", .event_data.key = TR_PARAMETER_VALUE_BUILDING_SMALL_TEMPLE_CERES, .building_model_data = {.cost = 50, .desirability_value = 4, .desirability_step = 2, - .desirability_step_size = 6, .desirability_range = 2, .laborers = 2} + .desirability_step_size = -1, .desirability_range = 6, .laborers = 2} }, [BUILDING_SMALL_TEMPLE_NEPTUNE] = { .venus_gt_bonus = 1, @@ -872,7 +918,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .event_data.attr = "small_temple_neptune", .event_data.key = TR_PARAMETER_VALUE_BUILDING_SMALL_TEMPLE_NEPTUNE, .building_model_data = {.cost = 50, .desirability_value = 4, .desirability_step = 2, - .desirability_step_size = 6, .desirability_range = 2, .laborers = 2} + .desirability_step_size = -1, .desirability_range = 6, .laborers = 2} }, [BUILDING_SMALL_TEMPLE_MERCURY] = { .venus_gt_bonus = 1, @@ -883,7 +929,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .event_data.attr = "small_temple_mercury", .event_data.key = TR_PARAMETER_VALUE_BUILDING_SMALL_TEMPLE_MERCURY, .building_model_data = {.cost = 50, .desirability_value = 4, .desirability_step = 2, - .desirability_step_size = 6, .desirability_range = 2, .laborers = 2} + .desirability_step_size = -1, .desirability_range = 6, .laborers = 2} }, [BUILDING_SMALL_TEMPLE_MARS] = { .venus_gt_bonus = 1, @@ -894,7 +940,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .event_data.attr = "small_temple_mars", .event_data.key = TR_PARAMETER_VALUE_BUILDING_SMALL_TEMPLE_MARS, .building_model_data = {.cost = 50, .desirability_value = 4, .desirability_step = 2, - .desirability_step_size = 6, .desirability_range = 2, .laborers = 2} + .desirability_step_size = -1, .desirability_range = 6, .laborers = 2} }, [BUILDING_SMALL_TEMPLE_VENUS] = { .venus_gt_bonus = 1, @@ -905,7 +951,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = { .event_data.attr = "small_temple_venus", .event_data.key = TR_PARAMETER_VALUE_BUILDING_SMALL_TEMPLE_VENUS, .building_model_data = {.cost = 50, .desirability_value = 4, .desirability_step = 2, - .desirability_step_size = 6, .desirability_range = 2, .laborers = 2} + .desirability_step_size = -1, .desirability_range = 6, .laborers = 2} }, [BUILDING_LARGE_TEMPLE_CERES] = { .venus_gt_bonus = 1, @@ -2230,7 +2276,7 @@ const building_properties *building_properties_for_type(building_type type) static model_building NOTHING = { .cost = 0, .desirability_value = 0, .desirability_step = 0, .desirability_step_size = 0, .desirability_range = 0, .laborers = 0 }; -void model_reset(void) +void model_reset_buildings(void) { for (building_type type = BUILDING_ANY; type < BUILDING_TYPE_MAX; type++) { const building_properties *props = &properties[type]; @@ -2244,25 +2290,39 @@ void model_reset(void) } } +void model_reset_houses(void) +{ + for (house_level level = HOUSE_MIN; level < HOUSE_MAX + 1; level++) { + const building_properties *props = &properties[level + 10]; + houses[level] = props->house_model_data; + } +} + +void model_reset(void) +{ + model_reset_buildings(); + model_reset_houses(); +} + void model_save_model_data(buffer *buf) { - int buf_size = sizeof(model_building) * BUILDING_TYPE_MAX; - uint8_t *buf_data = malloc(buf_size); + uint8_t *buf_data = malloc(BUFFER_SIZE); - buffer_init(buf, buf_data, buf_size); + buffer_init(buf, buf_data, BUFFER_SIZE); - buffer_write_raw(buf, buildings, buf_size); + buffer_write_raw(buf, buildings, BUFFER_SIZE - SIZE_HOUSES); + buffer_write_raw(buf, houses, BUFFER_SIZE - SIZE_BUILDINGS); } + void model_load_model_data(buffer *buf) { - int buf_size = sizeof(model_building) * BUILDING_TYPE_MAX; - - buffer_read_raw(buf, buildings, buf_size); + buffer_read_raw(buf, buildings, BUFFER_SIZE - SIZE_HOUSES); + buffer_read_raw(buf, houses, BUFFER_SIZE - SIZE_BUILDINGS); } -const model_house *model_get_house(house_level level) +model_house *model_get_house(house_level level) { - return &properties[level + 10].house_model_data; + return &houses[level]; } model_building *model_get_building(building_type type) @@ -2289,3 +2349,85 @@ int model_house_uses_inventory(house_level level, resource_type inventory) return 0; } } + +int *model_get_ptr_for_building_data_type(model_building *model, building_model_data_type data_type) +{ + switch (data_type) { + case MODEL_COST: + return &model->cost; + case MODEL_DESIRABILITY_VALUE: + return &model->desirability_value; + case MODEL_DESIRABILITY_STEP: + return &model->desirability_step; + case MODEL_DESIRABILITY_STEP_SIZE: + return &model->desirability_step_size; + case MODEL_DESIRABILITY_RANGE: + return &model->desirability_range; + case MODEL_LABORERS: + return &model->laborers; + default: + return &model->cost; + } +} + +int *model_get_ptr_for_house_data_type(model_house *model, house_model_data_type data_type) +{ + switch (data_type) { + case MODEL_DEVOLVE_DESIRABILITY: + return &model->devolve_desirability; + case MODEL_EVOLVE_DESIRABILITY: + return &model->evolve_desirability; + case MODEL_ENTERTAINMENT: + return &model->entertainment; + case MODEL_WATER: + return &model->water; + case MODEL_RELIGION: + return &model->religion; + case MODEL_EDUCATION: + return &model->education; + case MODEL_BARBER: + return &model->barber; + case MODEL_BATHHOUSE: + return &model->bathhouse; + case MODEL_HEALTH: + return &model->health; + case MODEL_FOOD_TYPES: + return &model->food_types; + case MODEL_POTTERY: + return &model->pottery; + case MODEL_OIL: + return &model->oil; + case MODEL_FURNITURE: + return &model->furniture; + case MODEL_WINE: + return &model->wine; + case MODEL_PROSPERITY: + return &model->prosperity; + case MODEL_MAX_PEOPLE: + return &model->max_people; + case MODEL_TAX_MULTIPLIER: + return &model->tax_multiplier; + default: + return &model->devolve_desirability; + } +} + +int model_get_min_for_data_type(building_model_data_type data_type) +{ + return min_max_for_data_types[data_type].min; +} + +int model_get_max_for_data_type(building_model_data_type data_type) +{ + return min_max_for_data_types[data_type].max; +} + +int model_get_min_for_house_data_type(house_model_data_type data_type) +{ + return min_max_for_house_data_types[data_type].min; +} + +int model_get_max_for_house_data_type(house_model_data_type data_type) +{ + return min_max_for_house_data_types[data_type].max; +} \ No newline at end of file diff --git a/src/building/properties.h b/src/building/properties.h index be744b5435..f2c4a7e586 100644 --- a/src/building/properties.h +++ b/src/building/properties.h @@ -26,7 +26,7 @@ typedef struct { int devolve_desirability; /**< Desirability at which the house devolves */ int evolve_desirability; /**< Desirability at which the house evolves */ int entertainment; /**< Entertainment points required */ - int water; /**< Water required: 1 = well, 2 = fountain */ + int water; /**< Water required: 1 = well, 2 = latrine or fountain, 3 = fountain */ int religion; /**< Number of gods required */ int education; /**< Education required: 1 = school or library, 2 = school and library, 3 = school, library and academy */ @@ -43,17 +43,49 @@ typedef struct { int tax_multiplier; /**< Tax rate multiplier */ } model_house; -enum { +typedef enum { MODEL_COST, MODEL_DESIRABILITY_VALUE, MODEL_DESIRABILITY_STEP, MODEL_DESIRABILITY_STEP_SIZE, MODEL_DESIRABILITY_RANGE, MODEL_LABORERS, -}; + + MODEL_BUILDING_MAX +} building_model_data_type; +typedef enum { + MODEL_DEVOLVE_DESIRABILITY, + MODEL_EVOLVE_DESIRABILITY, + MODEL_ENTERTAINMENT, + MODEL_WATER, + MODEL_RELIGION, + MODEL_EDUCATION, + MODEL_BARBER, + MODEL_BATHHOUSE, + MODEL_HEALTH, + MODEL_FOOD_TYPES, + MODEL_POTTERY, + MODEL_OIL, + MODEL_FURNITURE, + MODEL_WINE, + MODEL_PROSPERITY, + MODEL_MAX_PEOPLE, + MODEL_TAX_MULTIPLIER, + + MODEL_HOUSE_MAX +} house_model_data_type; + +/** + * Resets house model data from properties + */ +void model_reset_houses(void); /** - * Resets model data from properties + * Resets building model data from properties + */ +void model_reset_buildings(void); +/** + * Resets all model data from properties */ void model_reset(void); @@ -72,7 +104,7 @@ model_building *model_get_building(building_type type); * @param level House level * @return Read-only model */ -const model_house *model_get_house(house_level level); +model_house *model_get_house(house_level level); /** * Checks whether house level requires resource @@ -82,6 +114,23 @@ const model_house *model_get_house(house_level level); */ int model_house_uses_inventory(house_level level, resource_type inventory); +/** + * Return a pointer to read or edit model data for a given data_type + * @param model A pointer to a model to read the data from + * @param data_type The data_type to return the pointer for + */ +int *model_get_ptr_for_building_data_type(model_building *model, building_model_data_type data_type); +int *model_get_ptr_for_house_data_type(model_house *model, house_model_data_type data_type); + +/** + * Get min or max values for a specific data type + * @param data_type The data type + */ +int model_get_min_for_data_type(building_model_data_type data_type); +int model_get_max_for_data_type(building_model_data_type data_type); +int model_get_min_for_house_data_type(house_model_data_type data_type); +int model_get_max_for_house_data_type(house_model_data_type data_type); + // PROPERTIES typedef struct { diff --git a/src/building/storage.c b/src/building/storage.c index 0c62f9dbce..c6f2f3c366 100644 --- a/src/building/storage.c +++ b/src/building/storage.c @@ -22,7 +22,7 @@ #define STORAGE_STATIC_BUFFER_SIZE 10 #define STORAGE_CURRENT_BUFFER_SIZE (STORAGE_STATIC_BUFFER_SIZE + RESOURCE_MAX * 2) -static array(data_storage) storages; +static array(data_storage) storages = {0}; static void storage_create(data_storage *storage, unsigned int position) { diff --git a/src/core/lang.c b/src/core/lang.c index 5ba4e33cb8..e6bf1a6919 100644 --- a/src/core/lang.c +++ b/src/core/lang.c @@ -665,6 +665,9 @@ const uint8_t *lang_get_string(int group, int index) const uint8_t *lang_get_building_type_string(int type) { + if (type == BUILDING_NATIVE_CROPS) { + type = BUILDING_NATIVE_CROPS; // debug + } if (building_is_house(type) || type == BUILDING_NATIVE_MEETING || type == BUILDING_NATIVE_HUT || type == BUILDING_NATIVE_HUT_ALT || type == BUILDING_NATIVE_CROPS) { diff --git a/src/game/file_io.c b/src/game/file_io.c index 1364502feb..b440cb1856 100644 --- a/src/game/file_io.c +++ b/src/game/file_io.c @@ -229,7 +229,7 @@ typedef struct { buffer *deliveries; buffer *custom_empire; buffer *visited_buildings; - buffer *building_model_data; + buffer *model_data; buffer *rubble_grid; buffer *production_rates; } savegame_state; @@ -639,7 +639,7 @@ static void init_savegame_data(savegame_version_t version) state->message_media_metadata = create_savegame_piece(PIECE_SIZE_DYNAMIC, 0); } if (version_data.features.custom_model_data) { - state->building_model_data = create_savegame_piece(PIECE_SIZE_DYNAMIC, 0); + state->model_data = create_savegame_piece(PIECE_SIZE_DYNAMIC, 0); } state->max_game_year = create_savegame_piece(4, 0); state->earthquake = create_savegame_piece(60, 0); @@ -779,6 +779,9 @@ static void scenario_load_from_state(scenario_state *file, scenario_version_t ve scenario_events_migrate_to_grid_slices(); scenario_events_min_max_migrate_to_formulas(); } + if (version <= SCENARIO_LAST_NO_HOUSE_MODELS) { + model_reset_houses(); + } resource_init(); if (version > SCENARIO_LAST_NO_FORMULAS_AND_MODEL_DATA) { production_rates_load(file->production_rates); @@ -903,7 +906,10 @@ static void savegame_load_from_state(savegame_state *state, savegame_version_t v model_reset(); if (version > SAVE_GAME_LAST_NO_FORMULAS_AND_MODEL_DATA) { - model_load_model_data(state->building_model_data); + model_load_model_data(state->model_data); + } + if (version <= SAVE_GAME_LAST_NO_HOUSE_MODELS) { + model_reset_houses(); } resource_init(); @@ -1029,7 +1035,7 @@ static void savegame_save_to_state(savegame_state *state) game_time_save_state(state->game_time); random_save_state(state->random_iv); - model_save_model_data(state->building_model_data); + model_save_model_data(state->model_data); scenario_emperor_change_save_state(state->emperor_change_time, state->emperor_change_state); empire_save_state(state->empire); empire_save_custom_map(state->empire_map); diff --git a/src/game/resource.c b/src/game/resource.c index 297cb61994..128374675c 100644 --- a/src/game/resource.c +++ b/src/game/resource.c @@ -13,8 +13,6 @@ #include #include -#define RESOURCE_ALL (RESOURCE_MAX + RESOURCE_TOTAL_SPECIAL) - static const resource_type resource_mappings[][RESOURCE_ALL] = { { RESOURCE_NONE, RESOURCE_WHEAT, RESOURCE_VEGETABLES, RESOURCE_FRUIT, RESOURCE_OLIVES, RESOURCE_VINES, @@ -85,8 +83,8 @@ static resource_data resource_info_defaults[RESOURCE_ALL] = { [RESOURCE_WEAPONS] = { .type = RESOURCE_WEAPONS, .xml_attr_name = "weapons", .flags = RESOURCE_FLAG_STORABLE, .industry = BUILDING_WEAPONS_WORKSHOP, .production_per_month = 40, .default_trade_price = { 250, 180 } }, [RESOURCE_CONCRETE] = { .type = RESOURCE_CONCRETE, .xml_attr_name = "concrete", .flags = RESOURCE_FLAG_NONE, .industry = BUILDING_CONCRETE_MAKER, .production_per_month = 120 }, [RESOURCE_BRICKS] = { .type = RESOURCE_BRICKS, .xml_attr_name = "bricks", .flags = RESOURCE_FLAG_STORABLE, .industry = BUILDING_BRICKWORKS, .production_per_month = 60, .default_trade_price = { 200, 150 } }, - [RESOURCE_DENARII] = { .type = RESOURCE_DENARII, .industry = BUILDING_CITY_MINT, .production_per_month = 200 }, - [RESOURCE_TROOPS] = { .type = RESOURCE_TROOPS } + [RESOURCE_DENARII] = { .type = RESOURCE_DENARII, .xml_attr_name = "denarii", .industry = BUILDING_CITY_MINT, .production_per_month = 200 }, + [RESOURCE_TROOPS] = { .type = RESOURCE_TROOPS, .xml_attr_name = "troops", .industry = BUILDING_BARRACKS, .production_per_month = 100 } }; static resource_data resource_info[RESOURCE_ALL]; @@ -111,7 +109,7 @@ int resource_is_food(resource_type resource) int resource_is_raw_material(resource_type resource) { return resource != RESOURCE_NONE && !resource_is_food(resource) && - resource_get_supply_chain_for_good(0, resource) == 0; + resource_get_supply_chain_for_good(0, resource) == 0 && resource < RESOURCE_DENARII; } int resource_is_inventory(resource_type resource) @@ -126,10 +124,7 @@ int resource_is_storable(resource_type resource) resource_type resource_get_from_industry(building_type industry) { - if (industry == resource_info[RESOURCE_DENARII].industry) { - return RESOURCE_DENARII; - } - for (resource_type resource = RESOURCE_MIN; resource < RESOURCE_MAX; resource++) { + for (resource_type resource = RESOURCE_MIN; resource < RESOURCE_ALL; resource++) { if (resource_info[resource].industry == industry) { return resource; } @@ -167,7 +162,7 @@ int resource_get_supply_chain_for_raw_material(resource_supply_chain *chain, res void resource_init(void) { - memcpy(resource_info, resource_info_defaults, sizeof(resource_info_defaults)); + memcpy(resource_info, resource_info_defaults, sizeof(resource_data) * RESOURCE_ALL); int food_index = 0; int good_index = 0; diff --git a/src/game/resource.h b/src/game/resource.h index 4e7540c0f9..99a91368fe 100644 --- a/src/game/resource.h +++ b/src/game/resource.h @@ -63,7 +63,9 @@ typedef enum { RESOURCE_MAX_LEGACY = 16, RESOURCE_MAX_WITH_FISH = 17, RESOURCE_MAX_WITH_GOLD = 18, - RESOURCE_MAX_WITH_MONUMENT_RESOURCES = 22 + RESOURCE_MAX_WITH_MONUMENT_RESOURCES = 22, + + RESOURCE_ALL = RESOURCE_MAX + RESOURCE_TOTAL_SPECIAL } resource_type; #define LEGACY_INVENTORY_MAX 8 diff --git a/src/game/save_version.h b/src/game/save_version.h index 860a49098b..86591fe446 100644 --- a/src/game/save_version.h +++ b/src/game/save_version.h @@ -44,7 +44,7 @@ If you are unsure about anything regarding the savegame versioning, please ask o typedef enum { - SAVE_GAME_CURRENT_VERSION = 0xad, + SAVE_GAME_CURRENT_VERSION = 0xae, SAVE_GAME_LAST_ORIGINAL_LIMITS_VERSION = 0x66, SAVE_GAME_LAST_SMALLER_IMAGE_ID_VERSION = 0x76, @@ -97,11 +97,12 @@ typedef enum { SAVE_GAME_LAST_NO_FORMULAS_AND_MODEL_DATA = 0xa9, SAVE_GAME_LAST_STATIC_PATHS_AND_ROUTES = 0xaa, SAVE_GAME_LAST_NO_EMPIRE_EDITOR = 0xab, - SAVE_GAME_LAST_LIMITED_ROUTE_COST = 0xac + SAVE_GAME_LAST_LIMITED_ROUTE_COST = 0xac, + SAVE_GAME_LAST_NO_HOUSE_MODELS = 0xad } savegame_version_t; typedef enum { - SCENARIO_CURRENT_VERSION = 22, + SCENARIO_CURRENT_VERSION = 23, SCENARIO_VERSION_NONE = 0, SCENARIO_LAST_UNVERSIONED = 1, @@ -125,6 +126,7 @@ typedef enum { SCENARIO_LAST_NO_FORMULAS_AND_MODEL_DATA = 19, SCENARIO_LAST_NO_EMPIRE_EDITOR = 20, SCENARIO_LAST_LIMITED_ROUTE_COST = 21, + SCENARIO_LAST_NO_HOUSE_MODELS = 22 } scenario_version_t; typedef enum { diff --git a/src/graphics/font.c b/src/graphics/font.c index cf3fdd2b4d..bc9bc5b7db 100644 --- a/src/graphics/font.c +++ b/src/graphics/font.c @@ -561,6 +561,8 @@ static int font_character_beyond_mapping(const uint8_t *str) return IMAGE_FONT_CUSTOM_OFFSET + ASSET_FONT_CRLY_BRACKET_LEFT; case '}': return IMAGE_FONT_CUSTOM_OFFSET + ASSET_FONT_CRLY_BRACKET_RIGHT; + case '^': + return IMAGE_FONT_CUSTOM_OFFSET + ASSET_FONT_ABSTRACT_CARET_SYMBOL; default: return -1; } diff --git a/src/graphics/lang_text.c b/src/graphics/lang_text.c index 10a535808f..946ef8fe7a 100644 --- a/src/graphics/lang_text.c +++ b/src/graphics/lang_text.c @@ -29,6 +29,12 @@ void lang_text_draw_centered(int group, int number, int x_offset, int y_offset, text_draw_centered(str, x_offset, y_offset, box_width, font, 0); } +void lang_text_draw_centered_without_bounds(int group, int number, int x_offset, int y_offset, int box_width, font_t font) +{ + const uint8_t *str = lang_get_string(group, number); + text_draw_centered_without_bounds(str, x_offset, y_offset, box_width, font, 0); +} + void lang_text_draw_right_aligned(int group, int number, int x_offset, int y_offset, int box_width, font_t font) { const uint8_t *str = lang_get_string(group, number); diff --git a/src/graphics/lang_text.h b/src/graphics/lang_text.h index 35674cc541..ae4df390dc 100644 --- a/src/graphics/lang_text.h +++ b/src/graphics/lang_text.h @@ -28,6 +28,7 @@ int lang_text_draw(int group, int number, int x_offset, int y_offset, font_t fon int lang_text_draw_colored(int group, int number, int x_offset, int y_offset, font_t font, color_t color); void lang_text_draw_centered(int group, int number, int x_offset, int y_offset, int box_width, font_t font); +void lang_text_draw_centered_without_bounds(int group, int number, int x_offset, int y_offset, int box_width, font_t font); void lang_text_draw_right_aligned(int group, int number, int x_offset, int y_offset, int box_width, font_t font); void lang_text_draw_centered_colored( int group, int number, int x_offset, int y_offset, int box_width, font_t font, color_t color); diff --git a/src/graphics/scrollbar.c b/src/graphics/scrollbar.c index 0b7c301ead..8695a6b970 100644 --- a/src/graphics/scrollbar.c +++ b/src/graphics/scrollbar.c @@ -20,15 +20,6 @@ enum { static void text_scroll(int is_down, int num_lines); -static image_button image_button_scroll_up = { - 0, 0, SCROLL_BUTTON_WIDTH, SCROLL_BUTTON_HEIGHT, IB_SCROLL, - GROUP_OK_CANCEL_SCROLL_BUTTONS, 8, text_scroll, button_none, 0, 1, 1 -}; -static image_button image_button_scroll_down = { - 0, 0, SCROLL_BUTTON_WIDTH, SCROLL_BUTTON_HEIGHT, IB_SCROLL, - GROUP_OK_CANCEL_SCROLL_BUTTONS, 12, text_scroll, button_none, 1, 1, 1 -}; - static scrollbar_type *current; void scrollbar_init(scrollbar_type *scrollbar, unsigned int scroll_position, unsigned int total_elements) @@ -43,6 +34,11 @@ void scrollbar_init(scrollbar_type *scrollbar, unsigned int scroll_position, uns scrollbar->max_scroll_position = max_scroll_position; scrollbar->is_dragging_scrollbar_dot = 0; scrollbar->touch_drag_state = TOUCH_DRAG_NONE; + + scrollbar->image_button_scroll_up = (image_button){0, 0, SCROLL_BUTTON_WIDTH, SCROLL_BUTTON_HEIGHT, IB_SCROLL, + GROUP_OK_CANCEL_SCROLL_BUTTONS, 8, text_scroll, button_none, 0, 1, 1}; + scrollbar->image_button_scroll_down = (image_button){0, 0, SCROLL_BUTTON_WIDTH, SCROLL_BUTTON_HEIGHT, IB_SCROLL, + GROUP_OK_CANCEL_SCROLL_BUTTONS, 12, text_scroll, button_none, 1, 1, 1}; } void scrollbar_reset(scrollbar_type *scrollbar, unsigned int scroll_position) @@ -69,9 +65,9 @@ void scrollbar_update_total_elements(scrollbar_type *scrollbar, unsigned int tot void scrollbar_draw(scrollbar_type *scrollbar) { if (scrollbar->max_scroll_position > 0 || scrollbar->always_visible) { - image_buttons_draw(scrollbar->x, scrollbar->y, &image_button_scroll_up, 1); + image_buttons_draw(scrollbar->x, scrollbar->y, &scrollbar->image_button_scroll_up, 1); image_buttons_draw(scrollbar->x, scrollbar->y + scrollbar->height - SCROLL_BUTTON_HEIGHT, - &image_button_scroll_down, 1); + &scrollbar->image_button_scroll_down, 1); int pct; if (scrollbar->scroll_position <= 0) { @@ -184,12 +180,12 @@ int scrollbar_handle_mouse(scrollbar_type *scrollbar, const mouse *m, int in_dia } if (image_buttons_handle_mouse(m, - scrollbar->x, scrollbar->y, &image_button_scroll_up, 1, 0)) { + scrollbar->x, scrollbar->y, &scrollbar->image_button_scroll_up, 1, 0)) { return 1; } if (image_buttons_handle_mouse(m, scrollbar->x, scrollbar->y + scrollbar->height - SCROLL_BUTTON_HEIGHT, - &image_button_scroll_down, 1, 0)) { + &scrollbar->image_button_scroll_down, 1, 0)) { return 1; } } diff --git a/src/graphics/scrollbar.h b/src/graphics/scrollbar.h index 52085aa8ec..275f5778e7 100644 --- a/src/graphics/scrollbar.h +++ b/src/graphics/scrollbar.h @@ -3,6 +3,7 @@ #include "graphics/color.h" #include "graphics/font.h" +#include "graphics/image_button.h" #include "input/mouse.h" typedef struct { @@ -21,6 +22,9 @@ typedef struct { int scrollbar_dot_drag_offset; int touch_drag_state; int position_on_touch; + + image_button image_button_scroll_up; + image_button image_button_scroll_down; } scrollbar_type; /** diff --git a/src/graphics/text.c b/src/graphics/text.c index 0392aebbcd..16aafe5349 100644 --- a/src/graphics/text.c +++ b/src/graphics/text.c @@ -294,6 +294,15 @@ void text_draw_centered(const uint8_t *str, int x, int y, int box_width, font_t text_draw(str, offset + x, y, font, color); } +void text_draw_centered_without_bounds(const uint8_t *str, int x, int y, int box_width, font_t font, color_t color) +{ + int offset = (box_width - text_get_width(str, font)) / 2; + if (offset + x < 0) { + offset = 0; + } + text_draw(str, offset + x, y, font, color); +} + void text_draw_right_aligned(const uint8_t *str, int x, int y, int box_width, font_t font, color_t color) { int offset = box_width - text_get_width(str, font); diff --git a/src/graphics/text.h b/src/graphics/text.h index 3152264ca7..c17d672681 100644 --- a/src/graphics/text.h +++ b/src/graphics/text.h @@ -20,6 +20,7 @@ int text_draw(const uint8_t *str, int x, int y, font_t font, color_t color); int text_draw_scaled(const uint8_t *str, int x, int y, font_t font, color_t color, float scale); void text_draw_centered(const uint8_t *str, int x, int y, int box_width, font_t font, color_t color); +void text_draw_centered_without_bounds(const uint8_t *str, int x, int y, int box_width, font_t font, color_t color); void text_draw_right_aligned(const uint8_t *str, int x, int y, int box_width, font_t font, color_t color); int text_draw_ellipsized(const uint8_t *str, int x, int y, int box_width, font_t font, color_t color); diff --git a/src/input/keyboard.c b/src/input/keyboard.c index 5eb4585d77..4a847e0274 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -347,7 +347,7 @@ static int is_character_allowed(uint8_t c) return data.allow_punctuation; } else if (c == '"' || c == '%' || c == '\'' || c == '(' || c == ')' || c == '*' || c == '+' || c == '/' || c == ':' || c == ';' || - c == '=' || c == '_' || c == '[' || c == ']' || c == '{' || c == '}') { // fully supported punctuation + c == '=' || c == '_' || c == '[' || c == ']' || c == '{' || c == '}' || c == '^') { // fully supported punctuation return data.allow_punctuation; } else if (c >= 0x80) { // non-ASCII (UTF-8 continuation, etc.) return 1; diff --git a/src/scenario/criteria.c b/src/scenario/criteria.c index 8ba2a429a8..0bfc3addc3 100644 --- a/src/scenario/criteria.c +++ b/src/scenario/criteria.c @@ -4,6 +4,22 @@ static int max_game_year; +int scenario_criteria_get_max_value(scenario_win_condition_type condition) +{ + switch (condition) { + case SCENARIO_WIN_CONDITION_CULTURE: + case SCENARIO_WIN_CONDITION_PROSPERITY: + case SCENARIO_WIN_CONDITION_PEACE: + case SCENARIO_WIN_CONDITION_FAVOR: + return 100; + case SCENARIO_WIN_CONDITION_LOOSING_TIME: + case SCENARIO_WIN_CONDITION_WINNING_TIME: + return 999; + case SCENARIO_WIN_CONDITION_POPULATION: + return 99999; + } +} + int scenario_criteria_population_enabled(void) { return scenario.win_criteria.population.enabled; diff --git a/src/scenario/criteria.h b/src/scenario/criteria.h index 88767fb7d2..8fcabbe342 100644 --- a/src/scenario/criteria.h +++ b/src/scenario/criteria.h @@ -3,6 +3,18 @@ #include "core/buffer.h" +typedef enum { + SCENARIO_WIN_CONDITION_CULTURE, + SCENARIO_WIN_CONDITION_PROSPERITY, + SCENARIO_WIN_CONDITION_PEACE, + SCENARIO_WIN_CONDITION_FAVOR, + SCENARIO_WIN_CONDITION_LOOSING_TIME, + SCENARIO_WIN_CONDITION_WINNING_TIME, + SCENARIO_WIN_CONDITION_POPULATION, +} scenario_win_condition_type; + +int scenario_criteria_get_max_value(scenario_win_condition_type condition); + int scenario_criteria_population_enabled(void); int scenario_criteria_population(void); diff --git a/src/scenario/earthquake.c b/src/scenario/earthquake.c index 0bf85e2b3c..249317dd8b 100644 --- a/src/scenario/earthquake.c +++ b/src/scenario/earthquake.c @@ -12,6 +12,7 @@ #include "map/building.h" #include "map/data.h" #include "map/grid.h" +#include "map/point.h" #include "map/property.h" #include "map/routing_terrain.h" #include "map/terrain.h" @@ -34,11 +35,6 @@ static struct { int next_delay; } data; -struct field{ - int x; - int y; -}; - void scenario_earthquake_init(void) { data.game_year = scenario.start_year + scenario.earthquake.year; @@ -129,23 +125,23 @@ static void advance_earthquake_to_tile(int x, int y) figure_create_explosion_cloud(x, y, 1, 0); } -static struct field custom_earthquake_find_next_tile(void) +static map_point custom_earthquake_find_next_tile(void) { for (int y = 0; y < map_data.height; y++) { for (int x = 0; x < map_data.width; x++) { int grid_offset = map_grid_offset(x, y); if (map_property_is_future_earthquake(grid_offset) && can_advance_earthquake_to_tile(x, y)) { - return (struct field){x, y}; + return (map_point) {x, y}; } } } - return (struct field){0, 0}; + return (map_point){0, 0}; } static int custom_earthquake_advance_next_tile(void) { - struct field coords = custom_earthquake_find_next_tile(); + map_point coords = custom_earthquake_find_next_tile(); if (coords.x) { advance_earthquake_to_tile(coords.x, coords.y); int grid_offset = map_grid_offset(coords.x, coords.y); @@ -160,7 +156,7 @@ static int custom_earthquake_advance_next_tile(void) static int custom_earthquake_advance_random_tiles(void) { // 1. Collect all tiles that can be affected by the earthquake - struct field candidates[GRID_SIZE * GRID_SIZE]; + map_point candidates[GRID_SIZE * GRID_SIZE]; int count = 0; for (int y = 0; y < map_data.height; y++) { @@ -168,7 +164,7 @@ static int custom_earthquake_advance_random_tiles(void) int grid_offset = map_grid_offset(x, y); if (map_property_is_future_earthquake(grid_offset) && can_advance_earthquake_to_tile(x, y)) { - candidates[count++] = (struct field) { x, y }; + candidates[count++] = (map_point) { x, y }; } } } @@ -181,7 +177,7 @@ static int custom_earthquake_advance_random_tiles(void) for (int i = 0; i < tiles_to_process; i++) { int index = (scenario.earthquake.pattern == EARTHQUAKE_PATTERN_RANDOM ? random_short() : random_byte()) % count; // choose random out of candidates - struct field coords = candidates[index]; + map_point coords = candidates[index]; // Process the selected tile advance_earthquake_to_tile(coords.x, coords.y); @@ -210,7 +206,7 @@ void scenario_earthquake_process(void) if (data.state == EVENT_NOT_STARTED) { // Start event if (game_time_year() == data.game_year && game_time_month() == data.month) { data.state = EVENT_IN_PROGRESS; - struct field coords = custom_earthquake_find_next_tile(); + map_point coords = custom_earthquake_find_next_tile(); city_message_post(1, MESSAGE_EARTHQUAKE, 0, map_grid_offset(coords.x, coords.y)); } diff --git a/src/scenario/event/action_handler.c b/src/scenario/event/action_handler.c index 37ae162388..189b8f4e38 100644 --- a/src/scenario/event/action_handler.c +++ b/src/scenario/event/action_handler.c @@ -93,8 +93,12 @@ int scenario_action_type_execute(scenario_action_t *action) return scenario_action_type_change_rank_execute(action); case ACTION_TYPE_CHANGE_PRODUCTION_RATE: return scenario_action_type_change_production_rate_execute(action); + case ACTION_TYPE_CHANGE_HOUSE_MODEL_DATA: + return scenario_action_type_change_house_model_data_execute(action); case ACTION_TYPE_LOCK_TRADE_ROUTE: return scenario_action_type_lock_trade_route_execute(action); + case ACTION_TYPE_CHANGE_GOAL: + return scenario_action_type_change_goal_execute(action); default: return 0; } diff --git a/src/scenario/event/action_types.c b/src/scenario/event/action_types.c index eb7be81f6b..52e3a596ea 100644 --- a/src/scenario/event/action_types.c +++ b/src/scenario/event/action_types.c @@ -18,6 +18,7 @@ #include "city/trade.h" #include "city/victory.h" #include "core/random.h" +#include "core/calc.h" #include "empire/city.h" #include "empire/object.h" #include "empire/trade_prices.h" @@ -31,7 +32,9 @@ #include "map/terrain.h" #include "map/tiles.h" #include "scenario/allowed_building.h" +#include "scenario/criteria.h" #include "scenario/custom_variable.h" +#include "scenario/data.h" #include "scenario/event/controller.h" #include "scenario/event/formula.h" #include "scenario/event/parameter_city.h" @@ -768,30 +771,13 @@ int scenario_action_type_change_model_data_execute(scenario_action_t *action) int amount = scenario_formula_evaluate_formula(action->parameter3); int set_to_value = action->parameter4; + amount = calc_bound(amount, model_get_min_for_data_type(data_type), model_get_max_for_data_type(data_type)); + model_building *model_ptr = model_get_building(model); - switch (data_type) { - case MODEL_COST: - model_ptr->cost = set_to_value ? amount : amount + model_ptr->cost; - break; - case MODEL_DESIRABILITY_VALUE: - model_ptr->desirability_value = set_to_value ? amount : amount + model_ptr->desirability_value; - break; - case MODEL_DESIRABILITY_STEP: - model_ptr->desirability_step = set_to_value ? amount : amount + model_ptr->desirability_step; - break; - case MODEL_DESIRABILITY_STEP_SIZE: - model_ptr->desirability_step_size = set_to_value ? amount : amount + model_ptr->desirability_step_size; - break; - case MODEL_DESIRABILITY_RANGE: - model_ptr->desirability_range = set_to_value ? amount : amount + model_ptr->desirability_range; - break; - case MODEL_LABORERS: - model_ptr->laborers = set_to_value ? amount : amount + model_ptr->laborers; - break; - default: - break; - } + int *value = model_get_ptr_for_building_data_type(model_ptr, data_type); + *value = amount + (set_to_value ? 0 : *value); + return 1; } @@ -860,6 +846,23 @@ int scenario_action_type_change_production_rate_execute(scenario_action_t *actio return 1; } +int scenario_action_type_change_house_model_data_execute(scenario_action_t *action) +{ + int model = action->parameter1; + int data_type = action->parameter2; + int amount = scenario_formula_evaluate_formula(action->parameter3); + int set_to_value = action->parameter4; + + amount = calc_bound(amount, model_get_min_for_house_data_type(data_type), model_get_max_for_house_data_type(data_type)); + + model_house *model_ptr = model_get_house(model - 10); // convert from building type to housing + + int *value = model_get_ptr_for_house_data_type(model_ptr, data_type); + *value = amount + (set_to_value ? 0 : *value); + + return 1; +} + int scenario_action_type_lock_trade_route_execute(scenario_action_t *action) { int route_id = action->parameter1; @@ -886,6 +889,54 @@ int scenario_action_type_lock_trade_route_execute(scenario_action_t *action) empire_city_open_trade(city_id, 0); } building_menu_update(); + + return 1; +} + +int scenario_action_type_change_goal_execute(scenario_action_t *action) +{ + int win_condition = action->parameter1; + int value = scenario_formula_evaluate_formula(action->parameter2); + int set_to_value = action->parameter3; + value = calc_bound(value, 0, scenario_criteria_get_max_value(win_condition)); + switch(win_condition) { + case SCENARIO_WIN_CONDITION_CULTURE: + if (scenario_criteria_culture_enabled()) { + scenario.win_criteria.culture.goal = value + scenario.win_criteria.culture.goal * !set_to_value; + } + break; + case SCENARIO_WIN_CONDITION_PROSPERITY: + if (scenario_criteria_prosperity_enabled()) { + scenario.win_criteria.prosperity.goal = value + scenario.win_criteria.culture.goal * !set_to_value; + } + break; + case SCENARIO_WIN_CONDITION_PEACE: + if (scenario_criteria_peace_enabled()) { + scenario.win_criteria.peace.goal = value + scenario.win_criteria.culture.goal * !set_to_value; + } + break; + case SCENARIO_WIN_CONDITION_FAVOR: + if (scenario_criteria_favor_enabled()) { + scenario.win_criteria.favor.goal = value + scenario.win_criteria.culture.goal * !set_to_value; + } + break; + case SCENARIO_WIN_CONDITION_LOOSING_TIME: + if (scenario_criteria_time_limit_enabled()) { + scenario.win_criteria.time_limit.years = value + scenario.win_criteria.culture.goal * !set_to_value; + } + break; + case SCENARIO_WIN_CONDITION_WINNING_TIME: + if (scenario_criteria_survival_enabled()) { + scenario.win_criteria.survival_time.years = value + scenario.win_criteria.culture.goal * !set_to_value; + } + break; + case SCENARIO_WIN_CONDITION_POPULATION: + if (scenario_criteria_population_enabled()) { + scenario.win_criteria.population.goal = value + scenario.win_criteria.culture.goal * !set_to_value; + } + break; + } + return 1; } diff --git a/src/scenario/event/action_types.h b/src/scenario/event/action_types.h index 90b4e5aa91..2946fe7bcd 100644 --- a/src/scenario/event/action_types.h +++ b/src/scenario/event/action_types.h @@ -86,6 +86,10 @@ int scenario_action_type_change_rank_execute(scenario_action_t *action); int scenario_action_type_change_production_rate_execute(scenario_action_t *action); +int scenario_action_type_change_house_model_data_execute(scenario_action_t *action); + int scenario_action_type_lock_trade_route_execute(scenario_action_t *action); +int scenario_action_type_change_goal_execute(scenario_action_t *action); + #endif // ACTION_TYPES_H diff --git a/src/scenario/event/controller.c b/src/scenario/event/controller.c index bca782279a..5fb13262e0 100644 --- a/src/scenario/event/controller.c +++ b/src/scenario/event/controller.c @@ -461,75 +461,33 @@ void scenario_events_progress_paused(int days_passed) } } -static void migrate_parameters_action(scenario_action_t *action) +static void migrate_parameters_action(scenario_action_t *action, int **params, int index) { - // migration for older actions (pre-formulas) int min_limit = 0, max_limit = 0; - parameter_type p_type; - action_types action_type = action->type; - if (action_type == ACTION_TYPE_ADJUST_CITY_HEALTH || action_type == ACTION_TYPE_ADJUST_ROME_WAGES || - action_type == ACTION_TYPE_ADJUST_MONEY || action_type == ACTION_TYPE_ADJUST_SAVINGS) { - return; - } - int *params[] = { // Collect addresses of the fields - &action->parameter1, - &action->parameter2, - &action->parameter3, - &action->parameter4, - &action->parameter5 - }; - for (int i = 1; i <= 5; ++i) { - int *param_value = params[i - 1]; - p_type = scenario_events_parameter_data_get_action_parameter_type( - action_type, i, &min_limit, &max_limit); - if ((p_type == PARAMETER_TYPE_FORMULA || p_type == PARAMETER_TYPE_GRID_SLICE) && param_value != NULL) { - char buffer[16]; // Make sure buffer is large enough - memset(buffer, 0, sizeof(buffer)); - string_from_int((uint8_t *) buffer, *param_value, 0); - unsigned int id = scenario_formula_add((const uint8_t *) buffer, min_limit, max_limit); - switch (i) { - case 1: action->parameter1 = id; break; - case 2: action->parameter2 = id; break; - case 3: action->parameter3 = id; break; - case 4: action->parameter4 = id; break; - case 5: action->parameter5 = id; break; - } - } + int *param_value = params[index - 1]; + parameter_type p_type = scenario_events_parameter_data_get_action_parameter_type( + action->type, index, &min_limit, &max_limit); + if ((p_type == PARAMETER_TYPE_FORMULA || p_type == PARAMETER_TYPE_GRID_SLICE) && param_value != NULL) { + char buffer[16]; // Make sure buffer is large enough + memset(buffer, 0, sizeof(buffer)); + string_from_int((uint8_t *) buffer, *param_value, 0); + unsigned int id = scenario_formula_add((const uint8_t *) buffer, min_limit, max_limit); + *param_value = id; } } -static void migrate_parameters_condition(scenario_condition_t *condition) +static void migrate_parameters_condition(scenario_condition_t *condition, int **params, int index) { - // migration for older conditions (pre-formulas) int min_limit = 0, max_limit = 0; - parameter_type p_type; - condition_types condition_type = condition->type; - - int *params[] = { // Collect addresses of the fields - &condition->parameter1, - &condition->parameter2, - &condition->parameter3, - &condition->parameter4, - &condition->parameter5 - }; - - for (int i = 1; i <= 5; ++i) { - int *param_value = params[i - 1]; - p_type = scenario_events_parameter_data_get_condition_parameter_type( - condition_type, i, &min_limit, &max_limit); - if ((p_type == PARAMETER_TYPE_FORMULA || p_type == PARAMETER_TYPE_GRID_SLICE) && param_value != NULL) { - uint8_t buffer[16]; // Make sure buffer is large enough - memset(buffer, 0, sizeof(buffer)); - string_from_int(buffer, *param_value, 0); - unsigned int id = scenario_formula_add((const uint8_t *) buffer, min_limit, max_limit); - switch (i) { - case 1: condition->parameter1 = id; break; - case 2: condition->parameter2 = id; break; - case 3: condition->parameter3 = id; break; - case 4: condition->parameter4 = id; break; - case 5: condition->parameter5 = id; break; - } - } + int *param_value = params[index - 1]; + parameter_type p_type = scenario_events_parameter_data_get_condition_parameter_type( + condition->type, index, &min_limit, &max_limit); + if ((p_type == PARAMETER_TYPE_FORMULA || p_type == PARAMETER_TYPE_GRID_SLICE) && param_value != NULL) { + uint8_t buffer[16]; // Make sure buffer is large enough + memset(buffer, 0, sizeof(buffer)); + string_from_int(buffer, *param_value, 0); + unsigned int id = scenario_formula_add((const uint8_t *) buffer, min_limit, max_limit); + *param_value = id; } } @@ -552,7 +510,11 @@ void scenario_events_migrate_to_formulas(void) scenario_action_t *action; for (unsigned int j = 0; j < current->actions.size; j++) { action = array_item(current->actions, j); - migrate_parameters_action(action); //migrate parameters if needed + if (action->type == ACTION_TYPE_ADJUST_CITY_HEALTH || action->type == ACTION_TYPE_ADJUST_ROME_WAGES || + action->type == ACTION_TYPE_ADJUST_MONEY || action->type == ACTION_TYPE_ADJUST_SAVINGS) { + return; + } + scenario_parameters_foreach_in_action(action, migrate_parameters_action); //migrate parameters if needed } scenario_condition_group_t *group; scenario_condition_t *condition; @@ -560,7 +522,7 @@ void scenario_events_migrate_to_formulas(void) group = array_item(current->condition_groups, j); for (unsigned int k = 0; k < group->conditions.size; k++) { condition = array_item(group->conditions, k); - migrate_parameters_condition(condition); //migrate parameters if needed + scenario_parameters_foreach_in_condition(condition, migrate_parameters_condition); //migrate parameters if needed } } } @@ -602,6 +564,25 @@ void scenario_events_min_max_migrate_to_formulas(void) } } +void scenario_events_assign_parent_single_event_ids(scenario_event_t *event) +{ + int event_id = event->id; + scenario_action_t *action; + for (unsigned int i = 0; i < event->actions.size; i++) { + action = array_item(event->actions, i); + action->parent_event_id = event_id; + } + scenario_condition_group_t *group; + scenario_condition_t *condition; + for (unsigned int j = 0; j < event->condition_groups.size; j++) { + group = array_item(event->condition_groups, j); + for (unsigned int k = 0; k < group->conditions.size; k++) { + condition = array_item(group->conditions, k); + condition->parent_event_id = event_id; + } + } +} + void scenario_events_migrate_to_buys_sells(void) { scenario_event_t *current; @@ -629,21 +610,7 @@ void scenario_events_assign_parent_event_ids(void) scenario_event_t *current; array_foreach(scenario_events, current) //go through all events { - int event_id = current->id; - scenario_action_t *action; - for (unsigned int j = 0; j < current->actions.size; j++) { - action = array_item(current->actions, j); - action->parent_event_id = event_id; - } - scenario_condition_group_t *group; - scenario_condition_t *condition; - for (unsigned int j = 0; j < current->condition_groups.size; j++) { - group = array_item(current->condition_groups, j); - for (unsigned int k = 0; k < group->conditions.size; k++) { - condition = array_item(group->conditions, k); - condition->parent_event_id = event_id; - } - } + scenario_events_assign_parent_single_event_ids(current); } } diff --git a/src/scenario/event/controller.h b/src/scenario/event/controller.h index 311e683e12..30a7bbd861 100644 --- a/src/scenario/event/controller.h +++ b/src/scenario/event/controller.h @@ -31,11 +31,13 @@ void scenario_events_load_state(buffer *buf_events, buffer *buf_conditions, buff void scenario_events_process_all(void); void scenario_events_progress_paused(int days_passed); scenario_event_t *scenario_events_get_using_custom_variable(int custom_variable_id); + void scenario_events_migrate_to_resolved_display_names(void); void scenario_events_migrate_to_formulas(void); void scenario_events_min_max_migrate_to_formulas(void); void scenario_events_migrate_to_buys_sells(void); +void scenario_events_assign_parent_single_event_ids(scenario_event_t *event); void scenario_events_assign_parent_event_ids(void); void scenario_events_fetch_event_tiles_to_editor(void); diff --git a/src/scenario/event/data.h b/src/scenario/event/data.h index 3c3363804e..563f4d50a4 100644 --- a/src/scenario/event/data.h +++ b/src/scenario/event/data.h @@ -6,6 +6,9 @@ #include #define EVENT_NAME_LENGTH 32 +#define SCENARIO_ACTIONS_ARRAY_SIZE_STEP 20 +#define SCENARIO_CONDITIONS_ARRAY_SIZE_STEP 20 +#define SCENARIO_CONDITION_GROUPS_ARRAY_SIZE_STEP 2 #define CONDITION_GROUP_ITEMS_ARRAY_SIZE_STEP 2 #define CONDITION_GROUP_STRUCT_SIZE (2 * sizeof(uint32_t) + 1 * sizeof(uint16_t) + 1 * sizeof(uint8_t)) #define CONDITION_STRUCT_SIZE (5 * sizeof(int32_t) + 1 * sizeof(int16_t)) @@ -102,7 +105,9 @@ typedef enum { ACTION_TYPE_CHANGE_RANK = 41, ACTION_TYPE_CHANGE_MODEL_DATA = 42, ACTION_TYPE_CHANGE_PRODUCTION_RATE = 43, - ACTION_TYPE_LOCK_TRADE_ROUTE = 44, + ACTION_TYPE_CHANGE_HOUSE_MODEL_DATA = 44, + ACTION_TYPE_LOCK_TRADE_ROUTE = 45, + ACTION_TYPE_CHANGE_GOAL = 46, ACTION_TYPE_MAX, // helper constants ACTION_TYPE_MIN = ACTION_TYPE_ADJUST_FAVOR, diff --git a/src/scenario/event/event.c b/src/scenario/event/event.c index 5d6397ef50..a72194b572 100644 --- a/src/scenario/event/event.c +++ b/src/scenario/event/event.c @@ -6,10 +6,7 @@ #include "game/save_version.h" #include "scenario/event/action_handler.h" #include "scenario/event/condition_handler.h" - -#define SCENARIO_ACTIONS_ARRAY_SIZE_STEP 20 -#define SCENARIO_CONDITIONS_ARRAY_SIZE_STEP 20 -#define SCENARIO_CONDITION_GROUPS_ARRAY_SIZE_STEP 2 +#include "scenario/event/data.h" static int action_in_use(const scenario_action_t *action) { diff --git a/src/scenario/event/export_xml.c b/src/scenario/event/export_xml.c index 80460e1067..385e3d5874 100644 --- a/src/scenario/event/export_xml.c +++ b/src/scenario/event/export_xml.c @@ -77,7 +77,7 @@ static int export_attribute_route(xml_data_attribute_t *attr, int target) static int export_attribute_resource(xml_data_attribute_t *attr, int target) { - if (target < RESOURCE_MIN || target > RESOURCE_MAX) { + if (target < RESOURCE_MIN || target > RESOURCE_ALL) { log_exporting_error("Error while exporting resource."); return 0; } @@ -141,6 +141,7 @@ static int export_parse_attribute_with_resolved_type(xml_data_attribute_t *attr, case PARAMETER_TYPE_CLIMATE: case PARAMETER_TYPE_TERRAIN: case PARAMETER_TYPE_DATA_TYPE: + case PARAMETER_TYPE_HOUSE_DATA_TYPE: case PARAMETER_TYPE_MODEL: case PARAMETER_TYPE_PERCENTAGE: case PARAMETER_TYPE_HOUSING_TYPE: @@ -151,6 +152,7 @@ static int export_parse_attribute_with_resolved_type(xml_data_attribute_t *attr, case PARAMETER_TYPE_RANK: case PARAMETER_TYPE_CITY_PROPERTY: case PARAMETER_TYPE_MEDIA_TYPE: + case PARAMETER_TYPE_WIN_CONDITION: return export_attribute_by_type(attr, resolved_type, target); case PARAMETER_TYPE_BUILDING_COUNTING: return export_attribute_by_type(attr, PARAMETER_TYPE_BUILDING, target); @@ -168,6 +170,7 @@ static int export_parse_attribute_with_resolved_type(xml_data_attribute_t *attr, case PARAMETER_TYPE_GRID_SLICE: return export_attribute_number(attr, target); case PARAMETER_TYPE_RESOURCE: + case PARAMETER_TYPE_RESOURCE_ALL: return export_attribute_resource(attr, target); case PARAMETER_TYPE_ROUTE: return export_attribute_route(attr, target); diff --git a/src/scenario/event/formula.c b/src/scenario/event/formula.c index 219168ad0e..7029e7dec3 100644 --- a/src/scenario/event/formula.c +++ b/src/scenario/event/formula.c @@ -73,8 +73,9 @@ double parse_factor(const char **s) if (**s == ',') { (*s)++; double val2 = parse_expr(s); - val = val1 < val2 ? random_between_from_stdlib(val1, val2) : random_between_from_stdlib(val2, val1); + val = val1 < val2 ? random_between_from_stdlib(val1, val2 + 1) : random_between_from_stdlib(val2, val1 + 1); // random_between_from_stdlib does only work if min <= max otherwise it return min so the values have to be switched + // +1 to make {0,3} have the possible results 0 1 2 and 3 } if (**s == '}') { (*s)++; @@ -90,15 +91,29 @@ double parse_factor(const char **s) return 0.0; // fallback } -double parse_term(const char **s) +double parse_power(const char **s) { double val = parse_factor(s); skip_spaces(s); + + while (**s == '^') { + (*s)++; + double right = parse_factor(s); + val = pow(val, right); + } + + return val; +} + +double parse_term(const char **s) +{ + double val = parse_power(s); + skip_spaces(s); while (**s == '*' || **s == '/') { char op = **s; (*s)++; - double right = parse_factor(s); + double right = parse_power(s); skip_spaces(s); if (op == '*') { diff --git a/src/scenario/event/import_xml.c b/src/scenario/event/import_xml.c index e7530b396e..7dc2de78d8 100644 --- a/src/scenario/event/import_xml.c +++ b/src/scenario/event/import_xml.c @@ -21,7 +21,7 @@ #include #include -#define XML_TOTAL_ELEMENTS 77 +#define XML_TOTAL_ELEMENTS 78 #define ERROR_MESSAGE_LENGTH 200 static struct { @@ -142,6 +142,7 @@ static const xml_parser_element xml_elements[XML_TOTAL_ELEMENTS] = { { "change_rank", xml_import_create_action, 0, "actions"}, { "change_production_rate", xml_import_create_action, 0, "actions"}, { "lock_trade_route", xml_import_create_action, 0, "actions"}, + { "change_goal", xml_import_create_action, 0, "actions"} }; static int xml_import_start_scenario_events(void) @@ -502,6 +503,7 @@ static int xml_import_special_parse_attribute_with_resolved_type(xml_data_attrib case PARAMETER_TYPE_CLIMATE: case PARAMETER_TYPE_TERRAIN: case PARAMETER_TYPE_DATA_TYPE: + case PARAMETER_TYPE_HOUSE_DATA_TYPE: case PARAMETER_TYPE_MODEL: case PARAMETER_TYPE_PERCENTAGE: case PARAMETER_TYPE_HOUSING_TYPE: @@ -512,6 +514,7 @@ static int xml_import_special_parse_attribute_with_resolved_type(xml_data_attrib case PARAMETER_TYPE_RANK: case PARAMETER_TYPE_CITY_PROPERTY: case PARAMETER_TYPE_MEDIA_TYPE: + case PARAMETER_TYPE_WIN_CONDITION: return xml_import_special_parse_type(attr, resolved_type, target); case PARAMETER_TYPE_ROUTE_RESOURCE: return xml_import_special_parse_number(attr, target); @@ -526,6 +529,7 @@ static int xml_import_special_parse_attribute_with_resolved_type(xml_data_attrib case PARAMETER_TYPE_MIN_MAX_NUMBER: return xml_import_special_parse_min_max_number(attr, target); case PARAMETER_TYPE_RESOURCE: + case PARAMETER_TYPE_RESOURCE_ALL: return xml_import_special_parse_resource(attr, target); case PARAMETER_TYPE_ROUTE: return xml_import_special_parse_route(attr, target); @@ -629,7 +633,7 @@ static int xml_import_special_parse_resource(xml_data_attribute_t *attr, int *ta } const char *value = xml_parser_get_attribute_string(attr->name); - for (resource_type i = RESOURCE_MIN; i < RESOURCE_MAX; i++) { + for (resource_type i = RESOURCE_MIN; i < RESOURCE_ALL; i++) { const char *resource_name = resource_get_data(i)->xml_attr_name; if (xml_parser_compare_multiple(resource_name, value)) { *target = (int) i; diff --git a/src/scenario/event/parameter_data.c b/src/scenario/event/parameter_data.c index 3a9dd11e05..6eabfb4be8 100644 --- a/src/scenario/event/parameter_data.c +++ b/src/scenario/event/parameter_data.c @@ -16,6 +16,7 @@ #include "map/terrain.h" #include "scenario/event/controller.h" #include "scenario/event/parameter_city.h" +#include "scenario/criteria.h" #include "scenario/custom_messages.h" #include "scenario/custom_variable.h" #include "scenario/invasion.h" @@ -150,7 +151,7 @@ static scenario_condition_data_t scenario_condition_data[CONDITION_TYPE_MAX] = { .xml_parm2 = {.name = "grid_offset2", .type = PARAMETER_TYPE_GRID_SLICE, .min_limit = 0, .max_limit = UNLIMITED, .key = TR_PARAMETER_GRID_OFFSET_CORNER2 }, .xml_parm3 = {.name = "terrain_type", .type = PARAMETER_TYPE_TERRAIN, .key = TR_PARAMETER_TERRAIN }, .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_FORMULA, .min_limit = 0, .max_limit = UNLIMITED, .key = TR_PARAMETER_TYPE_FORMULA }, }, + .xml_parm5 = {.name = "value", .type = PARAMETER_TYPE_FORMULA, .min_limit = 0, .max_limit = UNLIMITED, .key = TR_PARAMETER_TYPE_FORMULA }, }, @@ -302,12 +303,10 @@ static scenario_action_data_t scenario_action_data[ACTION_TYPE_MAX] = { .xml_parm3 = {.name = "terrain", .type = PARAMETER_TYPE_TERRAIN, .key = TR_PARAMETER_TERRAIN }, .xml_parm4 = {.name = "add", .type = PARAMETER_TYPE_BOOLEAN, .min_limit = 0, .max_limit = 1, .key = TR_PARAMETER_ADD }, }, [ACTION_TYPE_CHANGE_MODEL_DATA] = {.type = ACTION_TYPE_CHANGE_MODEL_DATA, - .xml_attr = {.name = "change_model_data", .type = - PARAMETER_TYPE_TEXT, .key = TR_ACTION_TYPE_CHANGE_MODEL_DATA }, + .xml_attr = {.name = "change_model_data", .type = PARAMETER_TYPE_TEXT, .key = TR_ACTION_TYPE_CHANGE_MODEL_DATA }, .xml_parm1 = {.name = "model", .type = PARAMETER_TYPE_MODEL, .key = TR_PARAMETER_MODEL }, - .xml_parm2 = {.name = "data_type", .type = - PARAMETER_TYPE_DATA_TYPE, .key = TR_PARAMETER_DATA_TYPE }, + .xml_parm2 = {.name = "data_type", .type = PARAMETER_TYPE_DATA_TYPE, .key = TR_PARAMETER_DATA_TYPE }, .xml_parm3 = {.name = "amount", .type = PARAMETER_TYPE_FORMULA, .min_limit = NEGATIVE_UNLIMITED, .max_limit = UNLIMITED, .key = TR_PARAMETER_TYPE_FORMULA }, .xml_parm4 = {.name = "set_to_value", .type = PARAMETER_TYPE_BOOLEAN, .min_limit = 0, .max_limit = 1, .key = TR_PARAMETER_SET_TO_VALUE }, }, [ACTION_TYPE_CHANGE_CUSTOM_VARIABLE_VISIBILITY] = {.type = ACTION_TYPE_CHANGE_CUSTOM_VARIABLE_VISIBILITY, @@ -344,16 +343,31 @@ static scenario_action_data_t scenario_action_data[ACTION_TYPE_MAX] = { .xml_parm1 = {.name = "rank", .type = PARAMETER_TYPE_RANK, .key = TR_PARAMETER_TYPE_RANK }, }, [ACTION_TYPE_CHANGE_PRODUCTION_RATE] = {.type = ACTION_TYPE_CHANGE_PRODUCTION_RATE, .xml_attr = {.name = "change_production_rate", .type = PARAMETER_TYPE_TEXT, .key = TR_ACTION_TYPE_PRODUCTION_RATE}, - .xml_parm1 = {.name = "resource", .type = PARAMETER_TYPE_RESOURCE, .key = TR_PARAMETER_TYPE_RESOURCE }, + .xml_parm1 = {.name = "resource", .type = PARAMETER_TYPE_RESOURCE_ALL, .key = TR_PARAMETER_TYPE_RESOURCE }, .xml_parm2 = {.name = "rate", .type = PARAMETER_TYPE_FORMULA, .min_limit = 0, - .max_limit = UNLIMITED, .key = TR_PARAMETER_TYPE_NUMBER }, + .max_limit = UNLIMITED, .key = TR_PARAMETER_TYPE_FORMULA }, .xml_parm3 = {.name = "set_to_value", .type = PARAMETER_TYPE_BOOLEAN, .min_limit = 0, .max_limit = 1, .key = TR_PARAMETER_SET_TO_VALUE }, }, + [ACTION_TYPE_CHANGE_HOUSE_MODEL_DATA] = {.type = ACTION_TYPE_CHANGE_HOUSE_MODEL_DATA, + .xml_attr = {.name = "change_house_model_data", .type = PARAMETER_TYPE_TEXT, .key = TR_ACTION_TYPE_CHANGE_HOUSE_MODEL_DATA}, + .xml_parm1 = {.name = "housing_level", .type = PARAMETER_TYPE_HOUSING_TYPE, .key = TR_PARAMETER_TYPE_HOUSING_TYPE }, + .xml_parm2 = {.name = "house_data_type", .type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .key = TR_PARAMETER_DATA_TYPE}, + .xml_parm3 = {.name = "value", .type = PARAMETER_TYPE_FORMULA, .min_limit = 0, + .max_limit = UNLIMITED, .key = TR_PARAMETER_TYPE_NUMBER }, + .xml_parm4 = {.name = "set_to_value", .type = PARAMETER_TYPE_BOOLEAN, .min_limit = 0, + .max_limit = 1, .key = TR_PARAMETER_SET_TO_VALUE }, }, [ACTION_TYPE_LOCK_TRADE_ROUTE] = {.type = ACTION_TYPE_LOCK_TRADE_ROUTE, - .xml_attr = {.name = "lock_trade_route", .type = PARAMETER_TYPE_TEXT, .key = TR_ACTION_TYPE_LOCK_TRADE_ROUTE}, - .xml_parm1 = {.name = "target_city", .type = PARAMETER_TYPE_ROUTE, .key = TR_PARAMETER_TYPE_ROUTE }, - .xml_parm2 = {.name = "lock", .type = PARAMETER_TYPE_BOOLEAN, .min_limit = 0, .max_limit = 1, .key = TR_PARAMETER_LOCK }, - .xml_parm3 = {.name = "show_message", .type = PARAMETER_TYPE_BOOLEAN, .min_limit = 0, .max_limit = 1, .key = TR_PARAMETER_SHOW_MESSAGE } } + .xml_attr = {.name = "lock_trade_route", .type = PARAMETER_TYPE_TEXT, .key = TR_ACTION_TYPE_LOCK_TRADE_ROUTE}, + .xml_parm1 = {.name = "target_city", .type = PARAMETER_TYPE_ROUTE, .key = TR_PARAMETER_TYPE_ROUTE }, + .xml_parm2 = {.name = "lock", .type = PARAMETER_TYPE_BOOLEAN, .min_limit = 0, .max_limit = 1, .key = TR_PARAMETER_LOCK }, + .xml_parm3 = {.name = "show_message", .type = PARAMETER_TYPE_BOOLEAN, .min_limit = 0, .max_limit = 1, .key = TR_PARAMETER_SHOW_MESSAGE }, }, + [ACTION_TYPE_CHANGE_GOAL] = {.type = ACTION_TYPE_CHANGE_GOAL, + .xml_attr = {.name = "change_goal", .type = PARAMETER_TYPE_TEXT, .key = TR_ACTION_TYPE_CHANGE_GOAL}, + .xml_parm1 = {.name = "win_condition", .type = PARAMETER_TYPE_WIN_CONDITION, .key = TR_PARAMETER_TYPE_WIN_CONDITION}, + .xml_parm2 = {.name = "value", .type = PARAMETER_TYPE_FORMULA, .min_limit = 0, + .max_limit = UNLIMITED, .key = TR_PARAMETER_TYPE_FORMULA }, + .xml_parm3 = {.name = "set_to_value", .type = PARAMETER_TYPE_BOOLEAN, .min_limit = 0, + .max_limit = 1, .key = TR_PARAMETER_SET_TO_VALUE }, } }; scenario_action_data_t *scenario_events_parameter_data_get_actions_xml_attributes(action_types type) @@ -372,27 +386,39 @@ parameter_type scenario_events_parameter_data_get_action_parameter_type( switch (parameter_index) { case 1: + if (min_limit) *min_limit = action->xml_parm1.min_limit; + if (max_limit) *max_limit = action->xml_parm1.max_limit; return action->xml_parm1.type; case 2: + if (min_limit) *min_limit = action->xml_parm2.min_limit; + if (max_limit) *max_limit = action->xml_parm2.max_limit; return action->xml_parm2.type; case 3: + if (min_limit) *min_limit = action->xml_parm3.min_limit; + if (max_limit) *max_limit = action->xml_parm3.max_limit; return action->xml_parm3.type; case 4: + if (min_limit) *min_limit = action->xml_parm4.min_limit; + if (max_limit) *max_limit = action->xml_parm4.max_limit; return action->xml_parm4.type; case 5: + if (min_limit) *min_limit = action->xml_parm5.min_limit; + if (max_limit) *max_limit = action->xml_parm5.max_limit; return action->xml_parm5.type; default: + if (min_limit) *min_limit = 0; + if (max_limit) *max_limit = 0; return PARAMETER_TYPE_UNDEFINED; } @@ -409,27 +435,39 @@ parameter_type scenario_events_parameter_data_get_condition_parameter_type( switch (parameter_index) { case 1: + if (min_limit) *min_limit = condition->xml_parm1.min_limit; + if (max_limit) *max_limit = condition->xml_parm1.max_limit; return condition->xml_parm1.type; case 2: + if (min_limit) *min_limit = condition->xml_parm2.min_limit; + if (max_limit) *max_limit = condition->xml_parm2.max_limit; return condition->xml_parm2.type; case 3: + if (min_limit) *min_limit = condition->xml_parm3.min_limit; + if (max_limit) *max_limit = condition->xml_parm3.max_limit; return condition->xml_parm3.type; case 4: + if (min_limit) *min_limit = condition->xml_parm4.min_limit; + if (max_limit) *max_limit = condition->xml_parm4.max_limit; return condition->xml_parm4.type; case 5: + if (min_limit) *min_limit = condition->xml_parm5.min_limit; + if (max_limit) *max_limit = condition->xml_parm5.max_limit; return condition->xml_parm5.type; default: + if (min_limit) *min_limit = 0; + if (max_limit) *max_limit = 0; return PARAMETER_TYPE_UNDEFINED; } @@ -699,16 +737,39 @@ static special_attribute_mapping_t special_attribute_mappings_terrain[] = special_attribute_mapping_t special_attribute_mappings_data_type[] = { - {.type = PARAMETER_TYPE_DATA_TYPE, .text = "cost", .value = MODEL_COST, .key = TR_PARAMETER_COST }, - {.type = PARAMETER_TYPE_DATA_TYPE, .text = "desirability_value", .value = MODEL_DESIRABILITY_VALUE, .key = TR_PARAMETER_DESIRABILITY_VALUE }, - {.type = PARAMETER_TYPE_DATA_TYPE, .text = "desirability_step", .value = MODEL_DESIRABILITY_STEP, .key = TR_PARAMETER_DESIRABILITY_STEP }, - {.type = PARAMETER_TYPE_DATA_TYPE, .text = "desirability_step_size", .value = MODEL_DESIRABILITY_STEP_SIZE, .key = TR_PARAMETER_DESIRABILITY_STEP_SIZE }, - {.type = PARAMETER_TYPE_DATA_TYPE, .text = "desirability_range", .value = MODEL_DESIRABILITY_RANGE, .key = TR_PARAMETER_DESIRABILITY_RANGE }, - {.type = PARAMETER_TYPE_DATA_TYPE, .text = "laborers", .value = MODEL_LABORERS, .key = TR_PARAMETER_LABORERS }, + {.type = PARAMETER_TYPE_DATA_TYPE, .text = "cost", .value = MODEL_COST, .key = TR_PARAMETER_COST }, + {.type = PARAMETER_TYPE_DATA_TYPE, .text = "desirability_value", .value = MODEL_DESIRABILITY_VALUE, .key = TR_PARAMETER_DESIRABILITY_VALUE }, + {.type = PARAMETER_TYPE_DATA_TYPE, .text = "desirability_step", .value = MODEL_DESIRABILITY_STEP, .key = TR_PARAMETER_DESIRABILITY_STEP }, + {.type = PARAMETER_TYPE_DATA_TYPE, .text = "desirability_step_size", .value = MODEL_DESIRABILITY_STEP_SIZE, .key = TR_PARAMETER_DESIRABILITY_STEP_SIZE }, + {.type = PARAMETER_TYPE_DATA_TYPE, .text = "desirability_range", .value = MODEL_DESIRABILITY_RANGE, .key = TR_PARAMETER_DESIRABILITY_RANGE }, + {.type = PARAMETER_TYPE_DATA_TYPE, .text = "laborers", .value = MODEL_LABORERS, .key = TR_PARAMETER_LABORERS }, }; #define SPECIAL_ATTRIBUTE_MAPPINGS_DATA_TYPE_SIZE (sizeof(special_attribute_mappings_data_type) / sizeof(special_attribute_mapping_t)) +special_attribute_mapping_t special_attribute_mappings_house_data_type[] = +{ + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "devolve_desirability", .value = MODEL_DEVOLVE_DESIRABILITY, .key = TR_PARAMETER_DEVOLVE_DESIRABILITY }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "evolve_desirability", .value = MODEL_EVOLVE_DESIRABILITY, .key = TR_PARAMETER_EVOLVE_DESIRABILITY }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "entertainment", .value = MODEL_ENTERTAINMENT, .key = TR_PARAMETER_ENTERTAINMENT }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "water", .value = MODEL_WATER, .key = TR_PARAMETER_WATER }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "religion", .value = MODEL_RELIGION, .key = TR_PARAMETER_RELIGION }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "education", .value = MODEL_EDUCATION, .key = TR_PARAMETER_EDUCATION }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "barber", .value = MODEL_BARBER, .key = TR_PARAMETER_BARBER }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "bathhouse", .value = MODEL_BATHHOUSE, .key = TR_PARAMETER_BATHHOUSE }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "health", .value = MODEL_HEALTH, .key = TR_PARAMETER_HEALTH }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "food_types", .value = MODEL_FOOD_TYPES, .key = TR_PARAMETER_FOOD_TYPES }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "pottery", .value = MODEL_POTTERY, .key = TR_PARAMETER_POTTERY }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "oil", .value = MODEL_OIL, .key = TR_PARAMETER_OIL }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "furniture", .value = MODEL_FURNITURE, .key = TR_PARAMETER_FURNITURE }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "wine", .value = MODEL_WINE, .key = TR_PARAMETER_WINE }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "prosperity", .value = MODEL_PROSPERITY, .key = TR_PARAMETER_PROSPERITY }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "max_people", .value = MODEL_MAX_PEOPLE, .key = TR_PARAMETER_MAX_PEOPLE }, + {.type = PARAMETER_TYPE_HOUSE_DATA_TYPE, .text = "tax_multiplier", .value = MODEL_TAX_MULTIPLIER, .key = TR_PARAMETER_TAX_MULTIPLIER }, +}; + +#define SPECIAL_ATTRIBUTE_MAPPINGS_HOUSE_DATA_TYPE_SIZE (sizeof(special_attribute_mappings_house_data_type) / sizeof(special_attribute_mapping_t)) + static special_attribute_mapping_t special_attribute_mappings_percentage[] = { {.type = PARAMETER_TYPE_PERCENTAGE, .text = "Percentage", .value = 0, .key = TR_PARAMETER_PERCENTAGE }, {.type = PARAMETER_TYPE_PERCENTAGE, .text = "Absolute", .value = 1, .key = TR_PARAMETER_ABSOLUTE }, @@ -857,6 +918,17 @@ static special_attribute_mapping_t special_attribute_mappings_rank[] = { }; #define SPECIAL_ATTRIBUTE_MAPPINGS_RANK_SIZE (sizeof(special_attribute_mappings_rank) / sizeof(special_attribute_mapping_t)) +static special_attribute_mapping_t special_attribute_mappings_win_condition[] = { + {.type = PARAMETER_TYPE_WIN_CONDITION, .text = "culture", .value = SCENARIO_WIN_CONDITION_CULTURE, .key = TR_SCENARIO_WIN_CONDITION_CULTURE }, + {.type = PARAMETER_TYPE_WIN_CONDITION, .text = "properity", .value = SCENARIO_WIN_CONDITION_PROSPERITY, .key = TR_SCENARIO_WIN_CONDITION_PROSPERITY }, + {.type = PARAMETER_TYPE_WIN_CONDITION, .text = "peace", .value = SCENARIO_WIN_CONDITION_PEACE, .key = TR_SCENARIO_WIN_CONDITION_PEACE }, + {.type = PARAMETER_TYPE_WIN_CONDITION, .text = "favor", .value = SCENARIO_WIN_CONDITION_FAVOR, .key = TR_SCENARIO_WIN_CONDITION_FAVOR }, + {.type = PARAMETER_TYPE_WIN_CONDITION, .text = "loosing time", .value = SCENARIO_WIN_CONDITION_LOOSING_TIME, .key = TR_SCENARIO_WIN_CONDITION_LOOSING_TIME }, + {.type = PARAMETER_TYPE_WIN_CONDITION, .text = "winning time", .value = SCENARIO_WIN_CONDITION_WINNING_TIME, .key = TR_SCENARIO_WIN_CONDITION_WINNING_TIME }, + {.type = PARAMETER_TYPE_WIN_CONDITION, .text = "population", .value = SCENARIO_WIN_CONDITION_POPULATION, .key = TR_SCENARIO_WIN_CONDITION_POPULATION }, +}; +#define SPECIAL_ATTRIBUTE_MAPPINGS_WIN_CONDITION_SIZE (sizeof(special_attribute_mappings_win_condition) / sizeof(special_attribute_mapping_t)) + static void generate_building_type_mappings(void) { if (special_attribute_mappings_building_type_size > 0) { @@ -978,6 +1050,8 @@ special_attribute_mapping_t *scenario_events_parameter_data_get_attribute_mappin return &special_attribute_mappings_terrain[index]; case PARAMETER_TYPE_DATA_TYPE: return &special_attribute_mappings_data_type[index]; + case PARAMETER_TYPE_HOUSE_DATA_TYPE: + return &special_attribute_mappings_house_data_type[index]; case PARAMETER_TYPE_MODEL: generate_model_mappings(); return &special_attribute_mappings_model_buildings[index]; @@ -997,6 +1071,8 @@ special_attribute_mapping_t *scenario_events_parameter_data_get_attribute_mappin return &special_attribute_mappings_coverage_buildings[index]; case PARAMETER_TYPE_RANK: return &special_attribute_mappings_rank[index]; + case PARAMETER_TYPE_WIN_CONDITION: + return &special_attribute_mappings_win_condition[index]; default: return 0; } @@ -1042,6 +1118,8 @@ int scenario_events_parameter_data_get_mappings_size(parameter_type type) return SPECIAL_ATTRIBUTE_MAPPINGS_TERRAIN_SIZE; case PARAMETER_TYPE_DATA_TYPE: return SPECIAL_ATTRIBUTE_MAPPINGS_DATA_TYPE_SIZE; + case PARAMETER_TYPE_HOUSE_DATA_TYPE: + return SPECIAL_ATTRIBUTE_MAPPINGS_HOUSE_DATA_TYPE_SIZE; case PARAMETER_TYPE_MODEL: generate_model_mappings(); return special_attribute_mappings_model_buildings_size; @@ -1061,6 +1139,8 @@ int scenario_events_parameter_data_get_mappings_size(parameter_type type) return SPECIAL_ATTRIBUTE_MAPPINGS_COVERAGE_BUILDINGS_SIZE; case PARAMETER_TYPE_RANK: return SPECIAL_ATTRIBUTE_MAPPINGS_RANK_SIZE; + case PARAMETER_TYPE_WIN_CONDITION: + return SPECIAL_ATTRIBUTE_MAPPINGS_WIN_CONDITION_SIZE; default: return 0; } @@ -1116,6 +1196,7 @@ int scenario_events_parameter_data_get_default_value_for_parameter(xml_data_attr case PARAMETER_TYPE_ENEMY_TYPE: return ENEMY_UNDEFINED; case PARAMETER_TYPE_RESOURCE: + case PARAMETER_TYPE_RESOURCE_ALL: return RESOURCE_WHEAT; case PARAMETER_TYPE_POP_CLASS: return POP_CLASS_ALL; @@ -1140,6 +1221,8 @@ int scenario_events_parameter_data_get_default_value_for_parameter(xml_data_attr return TERRAIN_WATER; case PARAMETER_TYPE_DATA_TYPE: return MODEL_COST; + case PARAMETER_TYPE_HOUSE_DATA_TYPE: + return MODEL_EVOLVE_DESIRABILITY; case PARAMETER_TYPE_HOUSING_TYPE: return BUILDING_HOUSE_SMALL_TENT; case PARAMETER_TYPE_CITY_PROPERTY: @@ -1179,6 +1262,34 @@ parameter_type scenario_events_parameter_data_resolve_flexible_type(const scenar return info.param_types[param_index]; } +void scenario_parameters_foreach_in_action(scenario_action_t *action, void (*callback)(scenario_action_t *, int **, int)) +{ + int *params[] = { // Collect addresses of the fields + &action->parameter1, + &action->parameter2, + &action->parameter3, + &action->parameter4, + &action->parameter5 + }; + for (int i = 0; i < 5; i++) { + callback(action, params, i); + } +} + +void scenario_parameters_foreach_in_condition(scenario_condition_t *condition, void (*callback)(scenario_condition_t *, int **, int)) +{ + int *params[] = { // Collect addresses of the fields + &condition->parameter1, + &condition->parameter2, + &condition->parameter3, + &condition->parameter4, + &condition->parameter5 + }; + for (int i = 0; i < 5; i++) { + callback(condition, params, i); + } +} + static const uint8_t *get_allowed_building_name(building_type type) { if (type == BUILDING_HOUSE_VACANT_LOT) { @@ -1334,6 +1445,7 @@ void scenario_events_parameter_data_get_display_string_for_value(parameter_type return; } case PARAMETER_TYPE_RESOURCE: + case PARAMETER_TYPE_RESOURCE_ALL: { const uint8_t *text = resource_get_data(value)->text; result_text = string_copy(text, result_text, maxlength); @@ -1377,82 +1489,6 @@ static uint8_t *append_text(const uint8_t *text_to_append, uint8_t *result_text, return result_text; } -static uint8_t *translation_for_set_or_add_text(int parameter, uint8_t *result_text, int *maxlength) -{ - result_text = append_text(string_from_ascii(" "), result_text, maxlength); - if (parameter) { - result_text = append_text(translation_for(TR_PARAMETER_DISPLAY_SET_TO), result_text, maxlength); - } else { - result_text = append_text(translation_for(TR_PARAMETER_DISPLAY_ADD_TO), result_text, maxlength); - } - return result_text; -} - -static uint8_t *translation_for_min_max_values(int min, int max, uint8_t *result_text, int *maxlength) -{ - result_text = append_text(string_from_ascii(" "), result_text, maxlength); - result_text = append_text(translation_for(TR_PARAMETER_DISPLAY_BETWEEN), result_text, maxlength); - result_text = append_text(string_from_ascii(" "), result_text, maxlength); - - int number_length = string_from_int(result_text, min, 0); - result_text += number_length; - *maxlength -= number_length; - - result_text = append_text(string_from_ascii(".."), result_text, maxlength); - - number_length = string_from_int(result_text, max, 0); - result_text += number_length; - *maxlength -= number_length; - - return result_text; -} - -static uint8_t *translation_for_boolean_text(int value, translation_key true_key, translation_key false_key, uint8_t *result_text, int *maxlength) -{ - result_text = append_text(string_from_ascii(" "), result_text, maxlength); - if (value) { - result_text = append_text(translation_for(true_key), result_text, maxlength); - } else { - result_text = append_text(translation_for(false_key), result_text, maxlength); - } - - return result_text; -} - -static uint8_t *translation_for_formula_index(int index, uint8_t *result_text, int *maxlength) -{ - result_text = append_text(string_from_ascii(" "), result_text, maxlength); - - const uint8_t *text = scenario_formula_get_string(index); - if (text) { - result_text = append_text(text, result_text, maxlength); - } else { - result_text = append_text(string_from_ascii("???"), result_text, maxlength); - } - - return result_text; -} - -static uint8_t *translation_for_grid_offset(int value, uint8_t *result_text, int *maxlength) -{ - result_text = append_text(string_from_ascii(" "), result_text, maxlength); - - int number_length = string_from_int(result_text, value, 0); - result_text += number_length; - *maxlength -= number_length; - - return result_text; -} - -static uint8_t *translation_for_attr_mapping_text(parameter_type type, int value, uint8_t *result_text, int *maxlength) -{ - result_text = append_text(string_from_ascii(" "), result_text, maxlength); - special_attribute_mapping_t *attr_mapping = scenario_events_parameter_data_get_attribute_mapping_by_value(type, value); - - result_text = append_text(translation_for(attr_mapping->key), result_text, maxlength); - return result_text; -} - static uint8_t *translation_for_type_lookup_by_value(parameter_type type, int value, uint8_t *result_text, int *maxlength) { result_text = append_text(string_from_ascii(" "), result_text, maxlength); @@ -1460,512 +1496,46 @@ static uint8_t *translation_for_type_lookup_by_value(parameter_type type, int va uint8_t text[50]; memset(text, 0, 50); scenario_events_parameter_data_get_display_string_for_value(type, value, text, 50); + if (!*text) { + *result_text = '\0'; + maxlength++; + return --result_text; + } result_text = append_text(text, result_text, maxlength); return result_text; } -void scenario_events_parameter_data_get_display_string_for_action(const scenario_action_t *action, uint8_t *result_text, - int maxlength) +void scenario_events_parameter_data_get_display_string_for_action(const scenario_action_t *action, uint8_t *result_text, int maxlength) { scenario_action_data_t *xml_info = scenario_events_parameter_data_get_actions_xml_attributes(action->type); result_text = append_text(translation_for(xml_info->xml_attr.key), result_text, &maxlength); - switch (action->type) { - case ACTION_TYPE_ADJUST_CITY_HEALTH: - case ACTION_TYPE_ADJUST_ROME_WAGES: - { - result_text = translation_for_set_or_add_text(action->parameter2, result_text, &maxlength); - result_text = translation_for_formula_index(action->parameter1, result_text, &maxlength); - return; - } - case ACTION_TYPE_ADJUST_FAVOR: - { - result_text = translation_for_formula_index(action->parameter1, result_text, &maxlength); - return; - } - case ACTION_TYPE_ADJUST_MONEY: - case ACTION_TYPE_ADJUST_SAVINGS: - { - result_text = translation_for_formula_index(action->parameter1, result_text, &maxlength); - return; - } - 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_CORNER1), result_text, &maxlength); - result_text = translation_for_grid_offset(action->parameter1, result_text, &maxlength); - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = append_text(translation_for(TR_PARAMETER_GRID_OFFSET_CORNER2), result_text, &maxlength); - result_text = translation_for_grid_offset(action->parameter2, result_text, &maxlength); - if (action->parameter4) { - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = append_text(translation_for(TR_PARAMETER_DISPLAY_DESTROY_ALL_TYPES), result_text, &maxlength); - } else { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_BUILDING, action->parameter3, result_text, &maxlength); - } - return; - } - case ACTION_TYPE_CHANGE_ALLOWED_BUILDINGS: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_ALLOWED_BUILDING, action->parameter1, result_text, &maxlength); - result_text = translation_for_boolean_text(action->parameter2, TR_PARAMETER_DISPLAY_ALLOWED, TR_PARAMETER_DISPLAY_DISALLOWED, result_text, &maxlength); - return; - } - case ACTION_TYPE_CHANGE_CITY_RATING: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_RATING_TYPE, action->parameter1, result_text, &maxlength); - result_text = translation_for_set_or_add_text(action->parameter3, result_text, &maxlength); - result_text = translation_for_formula_index(action->parameter2, result_text, &maxlength); - return; - } - case ACTION_TYPE_CHANGE_CUSTOM_VARIABLE: - { - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - - if (scenario_custom_variable_exists(action->parameter1) && - scenario_custom_variable_get_name(action->parameter1)) { - result_text = append_text(scenario_custom_variable_get_name(action->parameter1), - result_text, &maxlength); - } else { - result_text = append_text(string_from_ascii("???"), result_text, &maxlength); - } - - result_text = translation_for_set_or_add_text(action->parameter3, result_text, &maxlength); - result_text = translation_for_formula_index(action->parameter2, result_text, &maxlength); - return; - } - case ACTION_TYPE_CHANGE_CUSTOM_VARIABLE_VISIBILITY: - { - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - - if (scenario_custom_variable_exists(action->parameter1) && - scenario_custom_variable_get_name(action->parameter1)) { - result_text = append_text(scenario_custom_variable_get_name(action->parameter1), - result_text, &maxlength); - } else { - result_text = append_text(string_from_ascii("???"), result_text, &maxlength); - } - - result_text = translation_for_boolean_text(action->parameter2, TR_PARAMETER_VALUE_BOOLEAN_TRUE, TR_PARAMETER_VALUE_BOOLEAN_FALSE, result_text, &maxlength); - return; - } - case ACTION_TYPE_CHANGE_RESOURCE_PRODUCED: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_RESOURCE, action->parameter1, result_text, &maxlength); - result_text = translation_for_boolean_text(action->parameter2, TR_PARAMETER_DISPLAY_ALLOWED, TR_PARAMETER_DISPLAY_DISALLOWED, result_text, &maxlength); - return; - } - case ACTION_TYPE_CHANGE_RESOURCE_STOCKPILES: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_STORAGE_TYPE, action->parameter3, result_text, &maxlength); - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_RESOURCE, action->parameter1, result_text, &maxlength); - result_text = translation_for_formula_index(action->parameter2, result_text, &maxlength); - result_text = translation_for_boolean_text(action->parameter4, TR_PARAMETER_DISPLAY_RESPECT_SETTINGS, TR_PARAMETER_DISPLAY_IGNORE_SETTINGS, result_text, &maxlength); - return; - } - case ACTION_TYPE_EMPIRE_MAP_CONVERT_FUTURE_TRADE_CITY: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_FUTURE_CITY, action->parameter1, result_text, &maxlength); - result_text = translation_for_boolean_text(action->parameter2, TR_PARAMETER_DISPLAY_SHOW_MESSAGE, TR_PARAMETER_DISPLAY_DO_NOT_SHOW_MESSAGE, result_text, &maxlength); - return; - } - case ACTION_TYPE_GLADIATOR_REVOLT: - { - return; - } - case ACTION_TYPE_INVASION_IMMEDIATE: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_INVASION_TYPE, action->parameter1, result_text, &maxlength); - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = append_text(translation_for(TR_PARAMETER_TYPE_INVASION_SIZE), result_text, &maxlength); - result_text = translation_for_formula_index(action->parameter2, result_text, &maxlength); - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_ENEMY_TYPE, action->parameter5, result_text, &maxlength); - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = append_text(translation_for(TR_PARAMETER_TYPE_INVASION_POINT), result_text, &maxlength); - result_text = translation_for_formula_index(action->parameter3, result_text, &maxlength); - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_TARGET_TYPE, action->parameter4, result_text, &maxlength); - return; - } - case ACTION_TYPE_REQUEST_IMMEDIATELY_START: - case ACTION_TYPE_TAX_RATE_SET: - { - result_text = translation_for_formula_index(action->parameter1, result_text, &maxlength); - return; - } - case ACTION_TYPE_TRADE_PROBLEM_LAND: - case ACTION_TYPE_TRADE_PROBLEM_SEA: - { - result_text = translation_for_formula_index(action->parameter1, result_text, &maxlength); - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = append_text(translation_for(TR_PARAMETER_DISPLAY_DAYS), result_text, &maxlength); - return; - } - case ACTION_TYPE_SEND_STANDARD_MESSAGE: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_STANDARD_MESSAGE, action->parameter1, result_text, &maxlength); - return; - } - case ACTION_TYPE_TRADE_ADJUST_PRICE: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_RESOURCE, action->parameter1, result_text, &maxlength); - result_text = translation_for_formula_index(action->parameter2, result_text, &maxlength); - result_text = translation_for_boolean_text(action->parameter3, TR_PARAMETER_DISPLAY_SHOW_MESSAGE, TR_PARAMETER_DISPLAY_DO_NOT_SHOW_MESSAGE, result_text, &maxlength); - return; - } - case ACTION_TYPE_TRADE_ADJUST_ROUTE_AMOUNT: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_ROUTE, action->parameter1, result_text, &maxlength); - result_text = translation_for_boolean_text(action->parameter5, TR_EDITOR_DEMAND_CHANGE_BUYS, TR_EDITOR_DEMAND_CHANGE_SELLS, result_text, &maxlength); - result_text = translation_for_formula_index(action->parameter3, result_text, &maxlength); - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_RESOURCE, action->parameter2, result_text, &maxlength); - result_text = translation_for_boolean_text(action->parameter4, TR_PARAMETER_DISPLAY_SHOW_MESSAGE, TR_PARAMETER_DISPLAY_DO_NOT_SHOW_MESSAGE, result_text, &maxlength); - return; - } - case ACTION_TYPE_TRADE_ROUTE_ADD_NEW_RESOURCE: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_ROUTE, action->parameter1, result_text, &maxlength); - result_text = translation_for_boolean_text(action->parameter4, TR_PARAMETER_DISPLAY_ADD_AS_BUYING, TR_PARAMETER_DISPLAY_ADD_AS_SELLING, result_text, &maxlength); - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_RESOURCE, action->parameter2, result_text, &maxlength); - result_text = translation_for_formula_index(action->parameter3, result_text, &maxlength); - result_text = translation_for_boolean_text(action->parameter5, TR_PARAMETER_DISPLAY_SHOW_MESSAGE, TR_PARAMETER_DISPLAY_DO_NOT_SHOW_MESSAGE, result_text, &maxlength); - return; - } - case ACTION_TYPE_TRADE_ADJUST_ROUTE_OPEN_PRICE: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_ROUTE, action->parameter1, result_text, &maxlength); - result_text = translation_for_set_or_add_text(action->parameter3, result_text, &maxlength); - result_text = translation_for_formula_index(action->parameter2, result_text, &maxlength); - result_text = translation_for_boolean_text(action->parameter4, TR_PARAMETER_DISPLAY_SHOW_MESSAGE, TR_PARAMETER_DISPLAY_DO_NOT_SHOW_MESSAGE, result_text, &maxlength); - return; - } - case ACTION_TYPE_TRADE_ROUTE_SET_OPEN: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_ROUTE, action->parameter1, result_text, &maxlength); - result_text = translation_for_boolean_text(action->parameter2, TR_PARAMETER_DISPLAY_APPLY_COST, TR_PARAMETER_DISPLAY_NO_COST, result_text, &maxlength); - return; - } - case ACTION_TYPE_TRADE_SET_PRICE: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_RESOURCE, action->parameter1, result_text, &maxlength); - result_text = translation_for_boolean_text(action->parameter3, TR_PARAMETER_DISPLAY_BUY_PRICE, TR_PARAMETER_DISPLAY_SELL_PRICE, result_text, &maxlength); - result_text = translation_for_formula_index(action->parameter2, result_text, &maxlength); - result_text = translation_for_boolean_text(action->parameter4, TR_PARAMETER_DISPLAY_SHOW_MESSAGE, TR_PARAMETER_DISPLAY_DO_NOT_SHOW_MESSAGE, result_text, &maxlength); - return; - } - case ACTION_TYPE_TRADE_SET_BUY_PRICE_ONLY: - case ACTION_TYPE_TRADE_SET_SELL_PRICE_ONLY: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_RESOURCE, action->parameter1, result_text, &maxlength); - result_text = translation_for_formula_index(action->parameter2, result_text, &maxlength); - return; - } - case ACTION_TYPE_SHOW_CUSTOM_MESSAGE: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_CUSTOM_MESSAGE, action->parameter1, result_text, &maxlength); - return; - } - case ACTION_TYPE_CAUSE_BLESSING: - case ACTION_TYPE_CAUSE_MINOR_CURSE: - case ACTION_TYPE_CAUSE_MAJOR_CURSE: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_GOD, action->parameter1, result_text, &maxlength); - return; - } - case ACTION_TYPE_CHANGE_CLIMATE: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_CLIMATE, action->parameter1, result_text, &maxlength); - return; - } - case ACTION_TYPE_CHANGE_TERRAIN: - { - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = append_text(translation_for(TR_PARAMETER_GRID_OFFSET_CORNER1), result_text, &maxlength); - result_text = translation_for_grid_offset(action->parameter1, result_text, &maxlength); - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = append_text(translation_for(TR_PARAMETER_GRID_OFFSET_CORNER2), result_text, &maxlength); - result_text = translation_for_grid_offset(action->parameter2, result_text, &maxlength); - if (action->parameter4) { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_TERRAIN, action->parameter3, result_text, &maxlength); - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = append_text(translation_for(TR_PARAMETER_ADD), result_text, &maxlength); - } else { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_TERRAIN, action->parameter3, result_text, &maxlength); - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = append_text(translation_for(TR_EDITOR_DELETE), result_text, &maxlength); - } - return; - } - case ACTION_TYPE_CHANGE_MODEL_DATA: - { - result_text = append_text(string_from_ascii(": "), result_text, &maxlength); - result_text = append_text(translation_for(action->parameter4 ? TR_PARAMETER_SET : TR_PARAMETER_CHANGE), result_text, &maxlength); - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_DATA_TYPE, action->parameter2, result_text, &maxlength); - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = append_text(translation_for(TR_PARAMETER_OF), result_text, &maxlength); - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_MODEL, action->parameter1, result_text, &maxlength); - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = append_text(translation_for(action->parameter4 ? TR_PARAMETER_TO : TR_PARAMETER_BY), result_text, &maxlength); - result_text = translation_for_formula_index(action->parameter3, result_text, &maxlength); - return; - case ACTION_TYPE_CUSTOM_VARIABLE_FORMULA: - { - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - if (scenario_custom_variable_exists(action->parameter1) && - scenario_custom_variable_get_name(action->parameter1)) { - result_text = append_text(scenario_custom_variable_get_name(action->parameter1), - result_text, &maxlength); - } else { - result_text = append_text(string_from_ascii("???"), result_text, &maxlength); - } - result_text = append_text(string_from_ascii(" = "), result_text, &maxlength); - // Get the formula string from the formula array - if (action->parameter2 > 0) { - const uint8_t *formula_str = scenario_formula_get_string(action->parameter2); - if (formula_str) { - result_text = append_text(formula_str, result_text, &maxlength); - } else { - result_text = append_text(string_from_ascii("???"), result_text, &maxlength); - } - } else { - result_text = append_text(string_from_ascii("0"), result_text, &maxlength); - } - return; - } - case ACTION_TYPE_CUSTOM_VARIABLE_CITY_PROPERTY: - { - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - if (scenario_custom_variable_exists(action->parameter1) && - scenario_custom_variable_get_name(action->parameter1)) { - result_text = append_text(scenario_custom_variable_get_name(action->parameter1), - result_text, &maxlength); - } else { - result_text = append_text(string_from_ascii("???"), result_text, &maxlength); - } - result_text = append_text(string_from_ascii(" = "), result_text, &maxlength); - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_CITY_PROPERTY, action->parameter2, result_text, &maxlength); - return; - } - case ACTION_TYPE_GOD_SENTIMENT_CHANGE: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_GOD, action->parameter1, result_text, &maxlength); - result_text = translation_for_set_or_add_text(action->parameter3, result_text, &maxlength); - // Get the formula string if parameter2 is a formula index - if (action->parameter2 > 0) { - const uint8_t *formula_str = scenario_formula_get_string(action->parameter2); - if (formula_str) { - result_text = append_text(formula_str, result_text, &maxlength); - } else { - result_text = translation_for_formula_index(action->parameter2, result_text, &maxlength); - } - } else { - result_text = translation_for_formula_index(action->parameter2, result_text, &maxlength); - } - return; - } - case ACTION_TYPE_POP_SENTIMENT_CHANGE: - { - result_text = translation_for_set_or_add_text(action->parameter2, result_text, &maxlength); - // Get the formula string if parameter1 is a formula index - if (action->parameter1 > 0) { - const uint8_t *formula_str = scenario_formula_get_string(action->parameter1); - if (formula_str) { - result_text = append_text(formula_str, result_text, &maxlength); - } else { - result_text = translation_for_formula_index(action->parameter1, result_text, &maxlength); - } - } else { - result_text = translation_for_formula_index(action->parameter1, result_text, &maxlength); - } - return; - } - case ACTION_TYPE_WIN: - case ACTION_TYPE_LOSE: - { - // No parameters to display - return; - } - case ACTION_TYPE_CHANGE_RANK: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_RANK, action->parameter1, result_text, &maxlength); - return; - } - case ACTION_TYPE_CHANGE_PRODUCTION_RATE: - { - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = append_text(translation_for(TR_PARAMETER_OF), result_text, &maxlength); - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_RESOURCE, action->parameter1, result_text, &maxlength); - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = append_text(translation_for(action->parameter3 ? TR_PARAMETER_BY : TR_PARAMETER_TO), result_text, &maxlength); - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = translation_for_formula_index(action->parameter2, result_text, &maxlength); - return; - } - case ACTION_TYPE_LOCK_TRADE_ROUTE: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_ROUTE, action->parameter1, result_text, &maxlength); - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = append_text(translation_for(action->parameter2 ? TR_PARAMETER_LOCK : TR_PARAMETER_UNLOCK), result_text, &maxlength); - result_text = translation_for_boolean_text(action->parameter3, TR_PARAMETER_DISPLAY_SHOW_MESSAGE, TR_PARAMETER_DISPLAY_DO_NOT_SHOW_MESSAGE, result_text, &maxlength); + int values[5] = {action->parameter1, action->parameter2, action->parameter3, action->parameter4, action->parameter5}; + xml_data_attribute_t attributes[5] = {xml_info->xml_parm1, xml_info->xml_parm2, xml_info->xml_parm3, xml_info->xml_parm4, xml_info->xml_parm5}; + for (int i = 0; i < 5; i++) { + if (!attributes[i].type || (action->type == ACTION_TYPE_CUSTOM_VARIABLE_CITY_PROPERTY && i >= 2)) { return; } - default: - { - result_text = append_text(string_from_ascii(" UNHANDLED ACTION TYPE!"), result_text, &maxlength); - return; - } - } + result_text = append_text(string_from_ascii("\n"), result_text, &maxlength); + result_text = append_text(translation_for(attributes[i].key), result_text, &maxlength); + result_text = append_text(string_from_ascii(":"), result_text, &maxlength); + result_text = translation_for_type_lookup_by_value(attributes[i].type , values[i], result_text, &maxlength); } } -void scenario_events_parameter_data_get_display_string_for_condition(const scenario_condition_t *condition, - uint8_t *result_text, int maxlength) + +void scenario_events_parameter_data_get_display_string_for_condition(const scenario_condition_t *condition, uint8_t *result_text, int maxlength) { scenario_condition_data_t *xml_info = scenario_events_parameter_data_get_conditions_xml_attributes(condition->type); result_text = append_text(translation_for(xml_info->xml_attr.key), result_text, &maxlength); - - switch (condition->type) { - case CONDITION_TYPE_BUILDING_COUNT_ACTIVE: - case CONDITION_TYPE_BUILDING_COUNT_ANY: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_BUILDING_COUNTING, condition->parameter3, result_text, &maxlength); - result_text = translation_for_attr_mapping_text(xml_info->xml_parm1.type, condition->parameter1, result_text, &maxlength); - result_text = translation_for_formula_index(condition->parameter2, result_text, &maxlength); - return; - } - case CONDITION_TYPE_CITY_POPULATION: - { - result_text = translation_for_attr_mapping_text(xml_info->xml_parm3.type, condition->parameter3, result_text, &maxlength); - result_text = translation_for_attr_mapping_text(xml_info->xml_parm1.type, condition->parameter1, result_text, &maxlength); - result_text = translation_for_formula_index(condition->parameter2, result_text, &maxlength); - return; - } - case CONDITION_TYPE_COUNT_OWN_TROOPS: - { - result_text = translation_for_boolean_text(condition->parameter3, TR_PARAMETER_DISPLAY_IN_CITY, TR_PARAMETER_DISPLAY_ANYWHERE, result_text, &maxlength); - result_text = translation_for_attr_mapping_text(xml_info->xml_parm1.type, condition->parameter1, result_text, &maxlength); - result_text = translation_for_formula_index(condition->parameter2, result_text, &maxlength); - return; - } - case CONDITION_TYPE_CUSTOM_VARIABLE_CHECK: - { - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - - if (scenario_custom_variable_exists(condition->parameter1) && - scenario_custom_variable_get_name(condition->parameter1)) { - result_text = append_text(scenario_custom_variable_get_name(condition->parameter1), result_text, &maxlength); - } else { - result_text = append_text(string_from_ascii("???"), result_text, &maxlength); - } - - result_text = translation_for_attr_mapping_text(xml_info->xml_parm2.type, condition->parameter2, result_text, &maxlength); - result_text = translation_for_formula_index(condition->parameter3, result_text, &maxlength); - return; - } - case CONDITION_TYPE_DIFFICULTY: - { - result_text = translation_for_attr_mapping_text(xml_info->xml_parm1.type, condition->parameter1, result_text, &maxlength); - result_text = translation_for_attr_mapping_text(xml_info->xml_parm2.type, condition->parameter2, result_text, &maxlength); - return; - } - case CONDITION_TYPE_MONEY: - case CONDITION_TYPE_SAVINGS: - case CONDITION_TYPE_STATS_FAVOR: - case CONDITION_TYPE_STATS_PROSPERITY: - case CONDITION_TYPE_STATS_CULTURE: - case CONDITION_TYPE_STATS_PEACE: - case CONDITION_TYPE_ROME_WAGES: - case CONDITION_TYPE_TAX_RATE: - case CONDITION_TYPE_STATS_CITY_HEALTH: - { - result_text = translation_for_attr_mapping_text(xml_info->xml_parm1.type, condition->parameter1, result_text, &maxlength); - result_text = translation_for_formula_index(condition->parameter2, result_text, &maxlength); - return; - } - case CONDITION_TYPE_POPS_UNEMPLOYMENT: - { - result_text = translation_for_boolean_text(condition->parameter1, TR_PARAMETER_DISPLAY_PERCENTAGE, TR_PARAMETER_DISPLAY_FLAT_NUMBER, result_text, &maxlength); - result_text = translation_for_attr_mapping_text(xml_info->xml_parm2.type, condition->parameter2, result_text, &maxlength); - result_text = translation_for_formula_index(condition->parameter3, result_text, &maxlength); - return; - } - case CONDITION_TYPE_REQUEST_IS_ONGOING: - { - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = translation_for_request_value(condition->parameter1, result_text, &maxlength); - 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: - case CONDITION_TYPE_TERRAIN_IN_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_grid_offset(condition->parameter1, result_text, &maxlength); - 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_grid_offset(condition->parameter2, result_text, &maxlength); - int param_type = condition->type == CONDITION_TYPE_BUILDING_COUNT_AREA ? PARAMETER_TYPE_BUILDING : PARAMETER_TYPE_TERRAIN; - result_text = translation_for_type_lookup_by_value(param_type, 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_formula_index(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); - result_text = translation_for_boolean_text(condition->parameter5, TR_PARAMETER_DISPLAY_RESPECT_SETTINGS, TR_PARAMETER_DISPLAY_IGNORE_SETTINGS, result_text, &maxlength); - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_RESOURCE, condition->parameter1, result_text, &maxlength); - result_text = translation_for_attr_mapping_text(xml_info->xml_parm2.type, condition->parameter2, result_text, &maxlength); - result_text = translation_for_formula_index(condition->parameter3, result_text, &maxlength); - return; - } - case CONDITION_TYPE_RESOURCE_STORED_COUNT: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_STORAGE_TYPE, condition->parameter4, result_text, &maxlength); - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_RESOURCE, condition->parameter1, result_text, &maxlength); - result_text = translation_for_attr_mapping_text(xml_info->xml_parm2.type, condition->parameter2, result_text, &maxlength); - result_text = translation_for_formula_index(condition->parameter3, result_text, &maxlength); - return; - } - case CONDITION_TYPE_TIME_PASSED: - { - result_text = translation_for_attr_mapping_text(xml_info->xml_parm1.type, condition->parameter1, result_text, &maxlength); - result_text = translation_for_min_max_values(condition->parameter2, condition->parameter3, result_text, &maxlength); - return; - } - case CONDITION_TYPE_TRADE_ROUTE_OPEN: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_ROUTE, condition->parameter1, result_text, &maxlength); - result_text = translation_for_boolean_text(condition->parameter2, TR_PARAMETER_DISPLAY_ROUTE_OPEN, TR_PARAMETER_DISPLAY_ROUTE_CLOSED, result_text, &maxlength); - return; - } - case CONDITION_TYPE_TRADE_ROUTE_PRICE: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_ROUTE, condition->parameter1, result_text, &maxlength); - result_text = translation_for_attr_mapping_text(xml_info->xml_parm2.type, condition->parameter2, result_text, &maxlength); - result_text = translation_for_formula_index(condition->parameter3, result_text, &maxlength); - return; - } - case CONDITION_TYPE_TRADE_SELL_PRICE: - { - result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_RESOURCE, condition->parameter1, result_text, &maxlength); - result_text = translation_for_attr_mapping_text(xml_info->xml_parm2.type, condition->parameter2, result_text, &maxlength); - result_text = translation_for_formula_index(condition->parameter3, result_text, &maxlength); - return; - } - case CONDITION_TYPE_CHECK_FORMULA: - { - result_text = append_text(string_from_ascii(" "), result_text, &maxlength); - result_text = translation_for_formula_index(condition->parameter1, result_text, &maxlength); - result_text = translation_for_attr_mapping_text(xml_info->xml_parm2.type, condition->parameter2, result_text, &maxlength); - result_text = translation_for_formula_index(condition->parameter3, result_text, &maxlength); - return; - } - - default: - { - result_text = append_text(string_from_ascii(" UNHANDLED CONDITION TYPE!"), result_text, &maxlength); + int values[5] = {condition->parameter1, condition->parameter2, condition->parameter3, condition->parameter4, condition->parameter5}; + xml_data_attribute_t attributes[5] = {xml_info->xml_parm1, xml_info->xml_parm2, xml_info->xml_parm3, xml_info->xml_parm4, xml_info->xml_parm5}; + for (int i = 0; i < 5; i++) { + if (!attributes[i].type) { return; } + result_text = append_text(string_from_ascii("\n"), result_text, &maxlength); + result_text = append_text(translation_for(attributes[i].key), result_text, &maxlength); + result_text = append_text(string_from_ascii(":"), result_text, &maxlength); + result_text = translation_for_type_lookup_by_value(attributes[i].type , values[i], result_text, &maxlength); } } diff --git a/src/scenario/event/parameter_data.h b/src/scenario/event/parameter_data.h index a6734ff7aa..2f73fba7a2 100644 --- a/src/scenario/event/parameter_data.h +++ b/src/scenario/event/parameter_data.h @@ -50,6 +50,9 @@ typedef enum { PARAMETER_TYPE_ROUTE_RESOURCE, //dynamic mapping of resource available on a route PARAMETER_TYPE_RANK, PARAMETER_TYPE_GRID_SLICE, + PARAMETER_TYPE_HOUSE_DATA_TYPE, + PARAMETER_TYPE_RESOURCE_ALL, + PARAMETER_TYPE_WIN_CONDITION } parameter_type; typedef struct { @@ -117,6 +120,9 @@ special_attribute_mapping_t *scenario_events_parameter_data_get_attribute_mappin special_attribute_mapping_t *scenario_events_parameter_data_get_attribute_mapping_by_text(parameter_type type, const char *value); int scenario_events_parameter_data_get_mappings_size(parameter_type type); +void scenario_parameters_foreach_in_action(scenario_action_t *action, void (*callback)(scenario_action_t *, int **, int)); +void scenario_parameters_foreach_in_condition(scenario_condition_t *condition, void (*callback)(scenario_condition_t *, int **, int)); + void scenario_events_parameter_data_sort_alphabetically(void); int scenario_events_parameter_data_get_default_value_for_parameter(xml_data_attribute_t *attribute_data); diff --git a/src/scenario/model_xml.c b/src/scenario/model_xml.c index 76f6f91ad2..94e21d0f23 100644 --- a/src/scenario/model_xml.c +++ b/src/scenario/model_xml.c @@ -26,6 +26,68 @@ static struct { int error_line_number; } data; +static const char *string_for_building_data_type(building_model_data_type data_type) +{ + switch (data_type) { + case MODEL_COST: + return "cost"; + case MODEL_DESIRABILITY_VALUE: + return "desirability_value"; + case MODEL_DESIRABILITY_STEP: + return "desirability_step"; + case MODEL_DESIRABILITY_STEP_SIZE: + return "desirability_step_size"; + case MODEL_DESIRABILITY_RANGE: + return "desirability_range"; + case MODEL_LABORERS: + return "laborers"; + default: + return "cost"; + } +} + +static const char *string_for_house_data_type(house_model_data_type data_type) +{ + switch (data_type) { + case MODEL_DEVOLVE_DESIRABILITY: + return "devolve_desirability"; + case MODEL_EVOLVE_DESIRABILITY: + return "evolve_desirability"; + case MODEL_ENTERTAINMENT: + return "entertainment"; + case MODEL_WATER: + return "water"; + case MODEL_RELIGION: + return "religion"; + case MODEL_EDUCATION: + return "education"; + case MODEL_BARBER: + return "barber"; + case MODEL_BATHHOUSE: + return "bathhouse"; + case MODEL_HEALTH: + return "health"; + case MODEL_FOOD_TYPES: + return "food_types"; + case MODEL_POTTERY: + return "pottery"; + case MODEL_OIL: + return "oil"; + case MODEL_FURNITURE: + return "furniture"; + case MODEL_WINE: + return "wine"; + case MODEL_PROSPERITY: + return "prosperity"; + case MODEL_MAX_PEOPLE: + return "max_people"; + case MODEL_TAX_MULTIPLIER: + return "tax_multiplier"; + default: + return "devolve_desirability"; + } +} + // EXPORT static void export_model_data(buffer *buf) @@ -58,7 +120,6 @@ static void export_model_data(buffer *buf) if (model == prop_model) { continue; } - if (memcmp(model, prop_model, sizeof(*model)) == 0) { continue; } @@ -66,12 +127,10 @@ static void export_model_data(buffer *buf) xml_exporter_new_element("building_model"); xml_exporter_add_attribute_text("building_type", props->event_data.attr); - xml_exporter_add_attribute_int("cost", model->cost); - xml_exporter_add_attribute_int("desirability_value", model->desirability_value); - xml_exporter_add_attribute_int("desirability_step", model->desirability_step); - xml_exporter_add_attribute_int("desirability_step_size", model->desirability_step_size); - xml_exporter_add_attribute_int("desirability_range", model->desirability_range); - xml_exporter_add_attribute_int("laborers", model->laborers); + + for (building_model_data_type data_type = MODEL_COST; data_type < MODEL_BUILDING_MAX; data_type++) { + xml_exporter_add_attribute_int(string_for_building_data_type(data_type), *model_get_ptr_for_building_data_type(model, data_type)); + } if ((building_is_raw_resource_producer(type) || building_is_workshop(type) || type == BUILDING_WHARF)) { if (resource->production_per_month != resource_get_defaults(resource_get_from_industry(type))->production_per_month) { xml_exporter_add_attribute_int("production_rate", resource->production_per_month); @@ -81,6 +140,33 @@ static void export_model_data(buffer *buf) edited_models++; } + + for (house_level level = HOUSE_MIN; level <= HOUSE_MAX; level++) { + const building_properties *props = building_properties_for_type(level + 10); + model_house *model = model_get_house(level); + model_house *prop_model = (model_house *) &props->house_model_data; + if (!model || !prop_model) { + continue; + } + + if (model == prop_model) { + continue; + } + if (memcmp(model, prop_model, sizeof(*model)) == 0) { + continue; + } + + xml_exporter_new_element("house_model"); + xml_exporter_add_attribute_text("house_level", props->event_data.attr); + + for (house_model_data_type data_type = MODEL_DEVOLVE_DESIRABILITY; data_type < MODEL_HOUSE_MAX; data_type++) { + xml_exporter_add_attribute_int(string_for_house_data_type(data_type), *model_get_ptr_for_house_data_type(model, data_type)); + } + + xml_exporter_close_element(); + + edited_models++; + } if (!edited_models) { xml_exporter_add_element_text(""); @@ -111,10 +197,12 @@ int scenario_model_export_to_xml(const char *filename) // IMPORT static int start_building_model(void); +static int start_house_model(void); -static const xml_parser_element xml_elements[2] = { +static const xml_parser_element xml_elements[3] = { {"model_data"}, - {"building_model", start_building_model, 0, "model_data"} + {"building_model", start_building_model, 0, "model_data"}, + {"house_model", start_house_model, 0, "model_data"} }; #define MAX_XML_ELEMENTS sizeof(xml_elements)/sizeof(xml_parser_element) @@ -140,40 +228,21 @@ static int start_building_model(void) return 0; } building_type type = found->value; - - if (!xml_parser_has_attribute("cost")) { - xml_import_log_error("Attribute missing. 'cost' not given"); - return 0; - } - if (!xml_parser_has_attribute("desirability_value")) { - xml_import_log_error("Attribute missing. 'desirability_value' not given"); - return 0; - } - if (!xml_parser_has_attribute("desirability_step")) { - xml_import_log_error("Attribute missing. 'desirability_step' not given"); - return 0; - } - if (!xml_parser_has_attribute("desirability_step_size")) { - xml_import_log_error("Attribute missing. 'desirability_step_size' not given"); - return 0; - } - if (!xml_parser_has_attribute("desirability_range")) { - xml_import_log_error("Attribute missing. 'desirability_range' not given"); - return 0; - } - if (!xml_parser_has_attribute("laborers")) { - xml_import_log_error("Attribute missing. 'laborers' not given"); - return 0; + + for (building_model_data_type data_type = MODEL_COST; data_type < MODEL_BUILDING_MAX; data_type++) { + if (!xml_parser_has_attribute(string_for_building_data_type(data_type))) { + char *error_msg; + snprintf(error_msg, 256, "Attribute missing. '%s' not given", string_for_building_data_type(data_type)); + xml_import_log_error(error_msg); + return 0; + } } model_building *model_ptr = model_get_building(type); - model_ptr->cost = xml_parser_get_attribute_int("cost"); - model_ptr->desirability_value = xml_parser_get_attribute_int("desirability_value"); - model_ptr->desirability_step = xml_parser_get_attribute_int("desirability_step"); - model_ptr->desirability_step_size = xml_parser_get_attribute_int("desirability_step_size"); - model_ptr->desirability_range = xml_parser_get_attribute_int("desirability_range"); - model_ptr->laborers = xml_parser_get_attribute_int("laborers"); + for (building_model_data_type data_type = MODEL_COST; data_type < MODEL_BUILDING_MAX; data_type++) { + *model_get_ptr_for_building_data_type(model_ptr, data_type) = xml_parser_get_attribute_int(string_for_building_data_type(data_type)); + } if (xml_parser_has_attribute("production_rate")) { resource_data *resource = resource_get_data(resource_get_from_industry(type)); resource->production_per_month = xml_parser_get_attribute_int("production_rate"); @@ -182,6 +251,34 @@ static int start_building_model(void) return 1; } +static int start_house_model(void) +{ + const char *value = xml_parser_get_attribute_string("house_level"); + special_attribute_mapping_t *found = scenario_events_parameter_data_get_attribute_mapping_by_text(PARAMETER_TYPE_MODEL, value); + if (found == 0) { + xml_import_log_error("Could not resolve the given value. Invalid house_level"); + return 0; + } + house_level level = found->value - 10; + + for (house_model_data_type data_type = MODEL_DEVOLVE_DESIRABILITY; data_type < MODEL_HOUSE_MAX; data_type++) { + if (!xml_parser_has_attribute(string_for_house_data_type(data_type))) { + char *error_msg; + snprintf(error_msg, 256, "Attribute missing. '%s' not given", string_for_house_data_type(data_type)); + xml_import_log_error(error_msg); + return 0; + } + } + + model_house *model_ptr = model_get_house(level); + + for (house_model_data_type data_type = MODEL_DEVOLVE_DESIRABILITY; data_type < MODEL_HOUSE_MAX; data_type++) { + *model_get_ptr_for_house_data_type(model_ptr, data_type) = xml_parser_get_attribute_int(string_for_house_data_type(data_type)); + } + + return 1; +} + static int parse_xml(char *buf, int buffer_length) { model_reset(); diff --git a/src/translation/english.c b/src/translation/english.c index 7ac221e8a7..75fd71ac09 100644 --- a/src/translation/english.c +++ b/src/translation/english.c @@ -1142,23 +1142,23 @@ static translation_string all_strings[] = { {TR_PARAMETER_TYPE_ROUTE, "Target trade route"}, {TR_PARAMETER_TYPE_STANDARD_MESSAGE, "Standard message"}, {TR_PARAMETER_TYPE_FUTURE_CITY, "Target future trade city"}, - {TR_PARAMETER_USE_PERCENTAGE, "Use percentage?"}, - {TR_PARAMETER_IN_CITY_ONLY, "Only count soldiers in the city?"}, - {TR_PARAMETER_CHECK_FOR_ONGOING, "Check that it is ongoing?"}, - {TR_PARAMETER_SHOW_MESSAGE, "Show message?"}, - {TR_PARAMETER_SET_TO_VALUE, "Set to value?"}, - {TR_PARAMETER_ADD_AS_BUYING, "Add as buying?"}, - {TR_PARAMETER_PRODUCED, "Produced?"}, - {TR_PARAMETER_ALLOWED, "Allowed?"}, - {TR_PARAMETER_SET_BUY_PRICE, "Set buy price?"}, - {TR_PARAMETER_CHECK_FOR_OPEN, "Check for route being open?"}, - {TR_PARAMETER_RESPECT_SETTINGS, "Respect storage settings?"}, + {TR_PARAMETER_USE_PERCENTAGE, "Use percentage"}, + {TR_PARAMETER_IN_CITY_ONLY, "Only count soldiers in the city"}, + {TR_PARAMETER_CHECK_FOR_ONGOING, "Check that it is ongoing"}, + {TR_PARAMETER_SHOW_MESSAGE, "Show message"}, + {TR_PARAMETER_SET_TO_VALUE, "Set to value"}, + {TR_PARAMETER_ADD_AS_BUYING, "Add as buying"}, + {TR_PARAMETER_PRODUCED, "Produced"}, + {TR_PARAMETER_ALLOWED, "Allowed"}, + {TR_PARAMETER_SET_BUY_PRICE, "Set buy price"}, + {TR_PARAMETER_CHECK_FOR_OPEN, "Check for route being open"}, + {TR_PARAMETER_RESPECT_SETTINGS, "Respect storage settings"}, {TR_PARAMETER_TYPE_CUSTOM_MESSAGE, "Custom message"}, {TR_PARAMETER_TYPE_CUSTOM_VARIABLE, "Custom variable"}, {TR_PARAMETER_TYPE_RATING_TYPE, "Rating type"}, {TR_PARAMETER_TYPE_STORAGE_TYPE, "Storage type"}, - {TR_PARAMETER_APPLY_COST, "Apply the open cost?"}, - {TR_PARAMETER_DESTROY_ALL, "Destroy all types?"}, + {TR_PARAMETER_APPLY_COST, "Apply the open cost"}, + {TR_PARAMETER_DESTROY_ALL, "Destroy all types"}, {TR_PARAMETER_GRID_OFFSET, "Grid offset"}, {TR_PARAMETER_RADIUS, "Radius"}, {TR_PARAMETER_TYPE_INVASION_SIZE, "Size"}, @@ -1909,6 +1909,62 @@ static translation_string all_strings[] = { {TR_BUILDING_HOUSE_LARGE_PALACE, "Large Palace"}, {TR_BUILDING_HOUSE_LUXURY_PALACE, "Luxury Palace"}, {TR_CONFIG_UI_BUILD_SHOW_RESERVOIR_RANGES, "Show reservoir range when building fountains"}, + {TR_ACTION_TYPE_CHANGE_HOUSE_MODEL_DATA, "Change house model data"}, + {TR_PARAMETER_DEVOLVE_DESIRABILITY, "Devolve desirability"}, + {TR_PARAMETER_EVOLVE_DESIRABILITY, "Evolve desirability"}, + {TR_PARAMETER_ENTERTAINMENT, "Entertainment"}, + {TR_PARAMETER_WATER, "Water"}, + {TR_PARAMETER_RELIGION, "Religion"}, + {TR_PARAMETER_EDUCATION, "Education"}, + {TR_PARAMETER_BARBER, "Barber"}, + {TR_PARAMETER_BATHHOUSE, "Bathhouse"}, + {TR_PARAMETER_HEALTH, "Health"}, + {TR_PARAMETER_FOOD_TYPES, "Food types"}, + {TR_PARAMETER_POTTERY, "Pottery"}, + {TR_PARAMETER_FURNITURE, "Furniture"}, + {TR_PARAMETER_OIL, "Oil"}, + {TR_PARAMETER_WINE, "Wine"}, + {TR_PARAMETER_PROSPERITY, "Prosperity"}, + {TR_PARAMETER_MAX_PEOPLE, "Max people"}, + {TR_PARAMETER_TAX_MULTIPLIER, "Tax multiplier"}, + {TR_PARAMETER_TYPE_HOUSING_TYPE, "Housing level"}, + {TR_PARAMETER_BUILDING_MODEL_REST_CONFIRMATION, "This only resets building model data."}, + {TR_CHEAT_DESTROYED_BUILDING, "Destroyed building"}, + {TR_PARAMETER_HOUSE_MODEL_REST_CONFIRMATION, "This only resets house model data."}, + {TR_EDITOR_HOUSE_MODEL_DEVOLVE_DESIRABILITY, "DVD"}, + {TR_EDITOR_HOUSE_MODEL_EVOLVE_DESIRABILITY, "EVD"}, + {TR_EDITOR_HOUSE_MODEL_ENTERTAINMENT, "ENT"}, + {TR_EDITOR_HOUSE_MODEL_WATER, "WTR"}, + {TR_EDITOR_HOUSE_MODEL_RELIGION, "RLG"}, + {TR_EDITOR_HOUSE_MODEL_EDUCATION, "EDU"}, + {TR_EDITOR_HOUSE_MODEL_BARBER, "BAR"}, + {TR_EDITOR_HOUSE_MODEL_BATHHOUSE, "BAH"}, + {TR_EDITOR_HOUSE_MODEL_HEALTH, "HEL"}, + {TR_EDITOR_HOUSE_MODEL_FOOD_TYPES, "FOT"}, + {TR_EDITOR_HOUSE_MODEL_POTTERY, "POT"}, + {TR_EDITOR_HOUSE_MODEL_FURNITURE, "FNT"}, + {TR_EDITOR_HOUSE_MODEL_OIL, "OIL"}, + {TR_EDITOR_HOUSE_MODEL_WINE, "WIN"}, + {TR_EDITOR_HOUSE_MODEL_PROSPERITY, "PSP"}, + {TR_EDITOR_HOUSE_MODEL_MAX_PEOPLE, "MPO"}, + {TR_EDITOR_HOUSE_MODEL_TAX_MULTIPLIER, "TMP"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_DEVOLVE_DESIRABILITY, "Devolve Desirability\nThe desirability that must be undercut for the house to devolve"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_EVOLVE_DESIRABILITY, "Evolve Desirability\nThe desirability that must be exceeded for the house to evolve"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_ENTERTAINMENT, "Entertainment\nThe entertainment value needed\ne.g. 10 is the value a theater provides"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_WATER, "Water\nWater level the house needs\n0: None, 1 = Well, 2 = Well + Latrine, 3 = Fountain"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_RELIGION, "Religion\nNumber of gods the house needs"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_EDUCATION, "Education\nEducational facilities needed\n0: None, 1 = School or Library, 2 = School and Library, 3 = School, Library and Academy"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_BARBER, "Barber\nWhether the house needs a barber 0 or 1"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_BATHHOUSE, "Bathhouse\nWhether the house needs bathhouse access 0 or 1"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_HEALTH, "Health\nHealth services needed\n1 = doctor or hospital, 2 = doctor and hospital"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_FOOD_TYPES, "Foodtypes\nThe number of different food types required"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_POTTERY, "Pottery\nWhether the house needs pottery 0 or 1"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_FURNITURE, "Furniture\nWhether the house needs furniture 0 or 1"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_OIL, "Oil\nWhether the house needs oil 0 or 1"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_WINE, "Wine\nWhether the house needs wine 0 or 1"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_PROSPERITY, "Prosperity\nThe amount the house distributes to the desirability cap"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_MAX_PEOPLE, "Max people\nHow many people can live in that housing type"}, + {TR_EDITOR_HOUSE_MODEL_EXPLANATION_TAX_MULTIPLIER, "Tax multiplier\nA multiplier for taxes"}, {TR_CONFIG_GP_CH_ALWAYS_DESTROY_BRIDGES, "Always allow removal of bridges"}, {TR_CONFIG_CATEGORY_MANAGEMENT_DESTRUCTION, "Destruction"}, {TR_CHEAT_DESTROYED_BUILDING, "Destroyed building"}, @@ -1958,6 +2014,20 @@ static translation_string all_strings[] = { {TR_ACTION_TYPE_LOCK_TRADE_ROUTE, "Lock Trade route"}, {TR_PARAMETER_LOCK, "Lock"}, {TR_PARAMETER_UNLOCK, "Unlock"}, + {TR_PARAMETER_TERRAIN_RUBBLE, "Rubble"}, + {TR_ACTION_TYPE_CHANGE_GOAL, "Change win criteria"}, + {TR_PARAMETER_TYPE_WIN_CONDITION, "Win condition"}, + {TR_SCENARIO_WIN_CONDITION_CULTURE, "Culture"}, + {TR_SCENARIO_WIN_CONDITION_PROSPERITY, "Prosperity"}, + {TR_SCENARIO_WIN_CONDITION_PEACE, "Peace"}, + {TR_SCENARIO_WIN_CONDITION_FAVOR, "Favor"}, + {TR_SCENARIO_WIN_CONDITION_LOOSING_TIME, "Time limit"}, + {TR_SCENARIO_WIN_CONDITION_WINNING_TIME, "Survival time"}, + {TR_SCENARIO_WIN_CONDITION_POPULATION, "Population"}, + {TR_EDITOR_COPY, "Copy"}, + {TR_EDITOR_PASTE, "Paste"}, + {TR_EDITOR_SCENARIO_EVENTS_COPY_SELECTED, "Copy selected"}, + {TR_EDITOR_SCENARIO_EVENTS_PASTE_SELECTED, "Paste selected"}, {TR_EMPIRE_DELETE_OBJECT, "Delete Object"}, {TR_EMPIRE_MOVE_OBJECT, "Move Object"}, {TR_CONFIG_UI_EMPIRE_CLICK_TO_DELETE, "Must click to delete object"}, diff --git a/src/translation/french.c b/src/translation/french.c index 59b7ebf385..2108ef8e1f 100644 --- a/src/translation/french.c +++ b/src/translation/french.c @@ -1141,23 +1141,23 @@ static translation_string all_strings[] = { {TR_PARAMETER_TYPE_ROUTE, "Concerne route commerciale"}, {TR_PARAMETER_TYPE_STANDARD_MESSAGE, "Message standard"}, {TR_PARAMETER_TYPE_FUTURE_CITY, "Concerne cité commerc. potentielle"}, - {TR_PARAMETER_USE_PERCENTAGE, "En pourcentage?"}, - {TR_PARAMETER_IN_CITY_ONLY, "Seulement les soldats dans la cité ?"}, - {TR_PARAMETER_CHECK_FOR_ONGOING, "Vérifier que requête en cours ?"}, - {TR_PARAMETER_SHOW_MESSAGE, "Afficher le message ?"}, - {TR_PARAMETER_SET_TO_VALUE, "Définir à cette valeur ?"}, - {TR_PARAMETER_ADD_AS_BUYING, "Ajouter comme achetant ?"}, - {TR_PARAMETER_PRODUCED, "Produite ?"}, - {TR_PARAMETER_ALLOWED, "Autorisé ?"}, - {TR_PARAMETER_SET_BUY_PRICE, "Appliquer au prix d'achat ?"}, - {TR_PARAMETER_CHECK_FOR_OPEN, "Vérifier que route ouverte ?"}, - {TR_PARAMETER_RESPECT_SETTINGS, "Respecter réglages stockage ?"}, + {TR_PARAMETER_USE_PERCENTAGE, "En pourcentage"}, + {TR_PARAMETER_IN_CITY_ONLY, "Seulement les soldats dans la cité"}, + {TR_PARAMETER_CHECK_FOR_ONGOING, "Vérifier que requête en cours"}, + {TR_PARAMETER_SHOW_MESSAGE, "Afficher le message"}, + {TR_PARAMETER_SET_TO_VALUE, "Définir à cette valeur"}, + {TR_PARAMETER_ADD_AS_BUYING, "Ajouter comme achetant"}, + {TR_PARAMETER_PRODUCED, "Produite"}, + {TR_PARAMETER_ALLOWED, "Autorisé"}, + {TR_PARAMETER_SET_BUY_PRICE, "Appliquer au prix d'achat"}, + {TR_PARAMETER_CHECK_FOR_OPEN, "Vérifier que route ouverte"}, + {TR_PARAMETER_RESPECT_SETTINGS, "Respecter réglages stockage"}, {TR_PARAMETER_TYPE_CUSTOM_MESSAGE, "Message perso."}, {TR_PARAMETER_TYPE_CUSTOM_VARIABLE, "Variable perso."}, {TR_PARAMETER_TYPE_RATING_TYPE, "Type évaluation"}, {TR_PARAMETER_TYPE_STORAGE_TYPE, "Type stockage"}, - {TR_PARAMETER_APPLY_COST, "Appliquer coût d'ouverture ?"}, - {TR_PARAMETER_DESTROY_ALL, "Détruire tous les types ?"}, + {TR_PARAMETER_APPLY_COST, "Appliquer coût d'ouverture"}, + {TR_PARAMETER_DESTROY_ALL, "Détruire tous les types"}, {TR_PARAMETER_GRID_OFFSET, "Offset grille"}, {TR_PARAMETER_RADIUS, "Rayon"}, {TR_PARAMETER_TYPE_INVASION_SIZE, "Taille"}, diff --git a/src/translation/german.c b/src/translation/german.c index c8cbd1ccf1..8af7344beb 100644 --- a/src/translation/german.c +++ b/src/translation/german.c @@ -1452,12 +1452,12 @@ static translation_string all_strings[] = { {TR_EDITOR_REPEAT_FREQUENCY_YEARS2, "Jahre:"}, {TR_EDITOR_REPEAT_FREQUENCY_MONTHS, "Monate"}, /* Missions-Editor - Parameter*/ - {TR_PARAMETER_ADD_AS_BUYING, "Als kaufend hinzufügen?"}, - {TR_PARAMETER_ALLOWED, "Erlaubt?"}, - {TR_PARAMETER_APPLY_COST, "Die 'öffnen' Kosten anwenden?"}, - {TR_PARAMETER_CHECK_FOR_ONGOING, "Prüfen, ob es eine laufende Maßnahme ist?"}, - {TR_PARAMETER_CHECK_FOR_OPEN, "Prüfen, ob die Route offen ist?"}, - {TR_PARAMETER_DESTROY_ALL, "Alle Arten zerstören?"}, + {TR_PARAMETER_ADD_AS_BUYING, "Als kaufend hinzufügen"}, + {TR_PARAMETER_ALLOWED, "Erlaubt"}, + {TR_PARAMETER_APPLY_COST, "Die 'öffnen' Kosten anwenden"}, + {TR_PARAMETER_CHECK_FOR_ONGOING, "Prüfen, ob es eine laufende Maßnahme ist"}, + {TR_PARAMETER_CHECK_FOR_OPEN, "Prüfen, ob die Route offen ist"}, + {TR_PARAMETER_DESTROY_ALL, "Alle Arten zerstören"}, {TR_PARAMETER_DISPLAY_ADD_AS_BUYING, "Als 'Kauft' hinzufügen"}, {TR_PARAMETER_DISPLAY_ADD_AS_SELLING, "Als 'Verkauft' hinzufügen"}, {TR_PARAMETER_DISPLAY_ADD_TO, "hinzufügen"}, diff --git a/src/translation/greek.c b/src/translation/greek.c index 481fb55c5a..d8df647d33 100644 --- a/src/translation/greek.c +++ b/src/translation/greek.c @@ -1054,7 +1054,7 @@ static translation_string all_strings[] = { {TR_PARAMETER_TYPE_ROUTE, "Εμπορική διαδρομή-στόχος"}, {TR_PARAMETER_TYPE_STANDARD_MESSAGE, "Κανονικό μήνυμα"}, {TR_PARAMETER_TYPE_FUTURE_CITY, "Στόχος μελλοντικής εμπορικής πόλης"}, - {TR_PARAMETER_USE_PERCENTAGE, "Χρήση ποσοστού?"}, + {TR_PARAMETER_USE_PERCENTAGE, "Χρήση ποσοστού"}, {TR_PARAMETER_IN_CITY_ONLY, "Να μετράτε μόνο τους στρατιώτες στην πόλη;"}, {TR_PARAMETER_CHECK_FOR_ONGOING, "Ελέγξτε ότι είναι σε εξέλιξη;"}, {TR_PARAMETER_SHOW_MESSAGE, "Εμφάνιση μηνύματος;"}, diff --git a/src/translation/italian.c b/src/translation/italian.c index 02ba106f8b..cdb175b902 100755 --- a/src/translation/italian.c +++ b/src/translation/italian.c @@ -1141,23 +1141,23 @@ static translation_string all_strings[] = { {TR_PARAMETER_TYPE_ROUTE, "Rotta commerciale obiettivo"}, {TR_PARAMETER_TYPE_STANDARD_MESSAGE, "Messaggio Standard"}, {TR_PARAMETER_TYPE_FUTURE_CITY, "Città di commercio obiettivo"}, - {TR_PARAMETER_USE_PERCENTAGE, "Usa percentuali?"}, - {TR_PARAMETER_IN_CITY_ONLY, "Conteggia solo i soldati in città?"}, - {TR_PARAMETER_CHECK_FOR_ONGOING, "Controlla che sia in corso?"}, - {TR_PARAMETER_SHOW_MESSAGE, "Mostra Messaggio?"}, - {TR_PARAMETER_SET_TO_VALUE, "Imposta al valore?"}, - {TR_PARAMETER_ADD_AS_BUYING, "Aggiungi come compratori?"}, - {TR_PARAMETER_PRODUCED, "Prodotti?"}, - {TR_PARAMETER_ALLOWED, "Permessi?"}, - {TR_PARAMETER_SET_BUY_PRICE, "Imposta prezzo di acquisto?"}, - {TR_PARAMETER_CHECK_FOR_OPEN, "Controlla che rotta commerciale aperta??"}, - {TR_PARAMETER_RESPECT_SETTINGS, "Rispetta le impostazioni di stoccaggio?"}, + {TR_PARAMETER_USE_PERCENTAGE, "Usa percentuali"}, + {TR_PARAMETER_IN_CITY_ONLY, "Conteggia solo i soldati in città"}, + {TR_PARAMETER_CHECK_FOR_ONGOING, "Controlla che sia in corso"}, + {TR_PARAMETER_SHOW_MESSAGE, "Mostra Messaggio"}, + {TR_PARAMETER_SET_TO_VALUE, "Imposta al valore"}, + {TR_PARAMETER_ADD_AS_BUYING, "Aggiungi come compratori"}, + {TR_PARAMETER_PRODUCED, "Prodotti"}, + {TR_PARAMETER_ALLOWED, "Permessi"}, + {TR_PARAMETER_SET_BUY_PRICE, "Imposta prezzo di acquisto"}, + {TR_PARAMETER_CHECK_FOR_OPEN, "Controlla che rotta commerciale aperta"}, + {TR_PARAMETER_RESPECT_SETTINGS, "Rispetta le impostazioni di stoccaggio"}, {TR_PARAMETER_TYPE_CUSTOM_MESSAGE, "Messaggio personalizzato"}, {TR_PARAMETER_TYPE_CUSTOM_VARIABLE, "Variabile personalizzata"}, {TR_PARAMETER_TYPE_RATING_TYPE, "Tipo rating"}, {TR_PARAMETER_TYPE_STORAGE_TYPE, "Tipo stoccaggio"}, - {TR_PARAMETER_APPLY_COST, "Applica costo aperto?"}, - {TR_PARAMETER_DESTROY_ALL, "Distruggi tutti i tipi?"}, + {TR_PARAMETER_APPLY_COST, "Applica costo aperto"}, + {TR_PARAMETER_DESTROY_ALL, "Distruggi tutti i tipi"}, {TR_PARAMETER_GRID_OFFSET, "Offset griglia"}, {TR_PARAMETER_RADIUS, "Raggio"}, {TR_PARAMETER_TYPE_INVASION_SIZE, "Dimensione"}, diff --git a/src/translation/korean.c b/src/translation/korean.c index 22cb7eb8ff..cfc9bac80f 100644 --- a/src/translation/korean.c +++ b/src/translation/korean.c @@ -1140,23 +1140,23 @@ static translation_string all_strings[] = { {TR_PARAMETER_TYPE_ROUTE, "대상 무역로"}, {TR_PARAMETER_TYPE_STANDARD_MESSAGE, "표준 메시지"}, {TR_PARAMETER_TYPE_FUTURE_CITY, "Target future trade city"}, - {TR_PARAMETER_USE_PERCENTAGE, "Use percentage?"}, - {TR_PARAMETER_IN_CITY_ONLY, "Only count soldiers in the city?"}, - {TR_PARAMETER_CHECK_FOR_ONGOING, "Check that it is ongoing?"}, - {TR_PARAMETER_SHOW_MESSAGE, "Show message?"}, - {TR_PARAMETER_SET_TO_VALUE, "Set to value?"}, - {TR_PARAMETER_ADD_AS_BUYING, "Add as buying?"}, - {TR_PARAMETER_PRODUCED, "Produced?"}, - {TR_PARAMETER_ALLOWED, "Allowed?"}, - {TR_PARAMETER_SET_BUY_PRICE, "Set buy price?"}, - {TR_PARAMETER_CHECK_FOR_OPEN, "Check for route being open?"}, - {TR_PARAMETER_RESPECT_SETTINGS, "Respect storage settings?"}, + {TR_PARAMETER_USE_PERCENTAGE, "Use percentage"}, + {TR_PARAMETER_IN_CITY_ONLY, "Only count soldiers in the city"}, + {TR_PARAMETER_CHECK_FOR_ONGOING, "Check that it is ongoing"}, + {TR_PARAMETER_SHOW_MESSAGE, "Show message"}, + {TR_PARAMETER_SET_TO_VALUE, "Set to value"}, + {TR_PARAMETER_ADD_AS_BUYING, "Add as buying"}, + {TR_PARAMETER_PRODUCED, "Produced"}, + {TR_PARAMETER_ALLOWED, "Allowed"}, + {TR_PARAMETER_SET_BUY_PRICE, "Set buy price"}, + {TR_PARAMETER_CHECK_FOR_OPEN, "Check for route being open"}, + {TR_PARAMETER_RESPECT_SETTINGS, "Respect storage settings"}, {TR_PARAMETER_TYPE_CUSTOM_MESSAGE, "Custom message"}, {TR_PARAMETER_TYPE_CUSTOM_VARIABLE, "Custom variable"}, {TR_PARAMETER_TYPE_RATING_TYPE, "Rating type"}, {TR_PARAMETER_TYPE_STORAGE_TYPE, "Storage type"}, - {TR_PARAMETER_APPLY_COST, "Apply the open cost?"}, - {TR_PARAMETER_DESTROY_ALL, "Destroy all types?"}, + {TR_PARAMETER_APPLY_COST, "Apply the open cost"}, + {TR_PARAMETER_DESTROY_ALL, "Destroy all types"}, {TR_PARAMETER_GRID_OFFSET, "Grid offset"}, {TR_PARAMETER_RADIUS, "Radius"}, {TR_PARAMETER_TYPE_INVASION_SIZE, "Size"}, diff --git a/src/translation/polish.c b/src/translation/polish.c index 3c61be4e4a..8e2614791e 100644 --- a/src/translation/polish.c +++ b/src/translation/polish.c @@ -1102,12 +1102,12 @@ static translation_string all_strings[] = { {TR_ORDER_CONDITION_NEVER, "Nigdy" }, {TR_ORDER_CONDITION_SOURCE_HAS_MORE_THAN, "Źródło ma więcej niż" }, {TR_OVERLAY_STORAGES, "Hurtownie" }, - {TR_PARAMETER_ADD_AS_BUYING, "Dodaj jako kupujące?"}, - {TR_PARAMETER_ALLOWED, "Dozwolone?"}, - {TR_PARAMETER_APPLY_COST, "Stosować otwarty koszt?"}, - {TR_PARAMETER_CHECK_FOR_ONGOING, "Sprawdzić, czy trwa?"}, - {TR_PARAMETER_CHECK_FOR_OPEN, "Sprawdzić, czy trasa jest otwarta?"}, - {TR_PARAMETER_DESTROY_ALL, "Zniszcz wszystkie rodzaje?"}, + {TR_PARAMETER_ADD_AS_BUYING, "Dodaj jako kupujące"}, + {TR_PARAMETER_ALLOWED, "Dozwolone"}, + {TR_PARAMETER_APPLY_COST, "Stosować otwarty koszt"}, + {TR_PARAMETER_CHECK_FOR_ONGOING, "Sprawdzić, czy trwa"}, + {TR_PARAMETER_CHECK_FOR_OPEN, "Sprawdzić, czy trasa jest otwarta"}, + {TR_PARAMETER_DESTROY_ALL, "Zniszcz wszystkie rodzaje"}, {TR_PARAMETER_DISPLAY_ADD_AS_BUYING, "dodaj jako kupujące"}, {TR_PARAMETER_DISPLAY_ADD_AS_SELLING, "dodaj jako sprzedające"}, {TR_PARAMETER_DISPLAY_ADD_TO, "dodaj"}, @@ -1135,13 +1135,13 @@ static translation_string all_strings[] = { {TR_PARAMETER_DISPLAY_SET_TO, "ustaw na"}, {TR_PARAMETER_DISPLAY_SHOW_MESSAGE, "pokaż wiadomość"}, {TR_PARAMETER_GRID_OFFSET, "Offset siatki"}, - {TR_PARAMETER_IN_CITY_ONLY, "Licz tylko żołnierzy w mieście?"}, - {TR_PARAMETER_PRODUCED, "Produkowane?"}, + {TR_PARAMETER_IN_CITY_ONLY, "Licz tylko żołnierzy w mieście"}, + {TR_PARAMETER_PRODUCED, "Produkowane"}, {TR_PARAMETER_RADIUS, "Promień"}, - {TR_PARAMETER_RESPECT_SETTINGS, "Zachowuj ustawienia przechowania?"}, - {TR_PARAMETER_SET_BUY_PRICE, "Ustaw cenę kupna?"}, - {TR_PARAMETER_SET_TO_VALUE, "Ustaw wartość?"}, - {TR_PARAMETER_SHOW_MESSAGE, "Pokaż wiadomość?"}, + {TR_PARAMETER_RESPECT_SETTINGS, "Zachowuj ustawienia przechowania"}, + {TR_PARAMETER_SET_BUY_PRICE, "Ustaw cenę kupna"}, + {TR_PARAMETER_SET_TO_VALUE, "Ustaw wartość"}, + {TR_PARAMETER_SHOW_MESSAGE, "Pokaż wiadomość"}, {TR_PARAMETER_TYPE_ALLOWED_BUILDING, "Dozwolony rodzaj budynku"}, {TR_PARAMETER_TYPE_BOOLEAN, "Prawda lub fałsz"}, {TR_PARAMETER_TYPE_BUILDING_COUNTING, "Rodzaj budynku dla liczenia"}, @@ -1164,7 +1164,7 @@ static translation_string all_strings[] = { {TR_PARAMETER_TYPE_STANDARD_MESSAGE, "Standardowa wiadomość"}, {TR_PARAMETER_TYPE_STORAGE_TYPE, "Rodzaj przechowania"}, {TR_PARAMETER_TYPE_TARGET_TYPE, "Rodzaj celu"}, - {TR_PARAMETER_USE_PERCENTAGE, "Użyj procent?"}, + {TR_PARAMETER_USE_PERCENTAGE, "Użyj procent"}, {TR_PARAMETER_VALUE_BOOLEAN_FALSE, "Fałsz"}, {TR_PARAMETER_VALUE_BOOLEAN_TRUE, "Prawda"}, {TR_PARAMETER_VALUE_BUILDING_ANY, "Jakiekolwiek"}, diff --git a/src/translation/portuguese.c b/src/translation/portuguese.c index b78a1b7188..fbfd69e51e 100644 --- a/src/translation/portuguese.c +++ b/src/translation/portuguese.c @@ -1116,12 +1116,12 @@ static translation_string all_strings[] = { {TR_ORDER_CONDITION_NEVER, "Nunca" }, {TR_ORDER_CONDITION_SOURCE_HAS_MORE_THAN, "O destino tem mais de" }, {TR_OVERLAY_STORAGES, "Estoques" }, - {TR_PARAMETER_ADD_AS_BUYING, "Adicionar como compra?"}, - {TR_PARAMETER_ALLOWED, "Permitido?"}, - {TR_PARAMETER_APPLY_COST, "Aplicar o custo de abertura?"}, - {TR_PARAMETER_CHECK_FOR_ONGOING, "Conferir continuidade?"}, - {TR_PARAMETER_CHECK_FOR_OPEN, "Conferir abertura de rota?"}, - {TR_PARAMETER_DESTROY_ALL, "Demolir todos os tipos?"}, + {TR_PARAMETER_ADD_AS_BUYING, "Adicionar como compra"}, + {TR_PARAMETER_ALLOWED, "Permitido"}, + {TR_PARAMETER_APPLY_COST, "Aplicar o custo de abertura"}, + {TR_PARAMETER_CHECK_FOR_ONGOING, "Conferir continuidade"}, + {TR_PARAMETER_CHECK_FOR_OPEN, "Conferir abertura de rota"}, + {TR_PARAMETER_DESTROY_ALL, "Demolir todos os tipos"}, {TR_PARAMETER_DISPLAY_ADD_AS_BUYING, "adicionar como compra"}, {TR_PARAMETER_DISPLAY_ADD_AS_SELLING, "adicionar como venda"}, {TR_PARAMETER_DISPLAY_ADD_TO, "adicionar"}, @@ -1148,13 +1148,13 @@ static translation_string all_strings[] = { {TR_PARAMETER_DISPLAY_SET_TO, "definir como"}, {TR_PARAMETER_DISPLAY_SHOW_MESSAGE, "mostrar mensagem"}, {TR_PARAMETER_GRID_OFFSET, "Posição da grade"}, - {TR_PARAMETER_IN_CITY_ONLY, "Contar apenas soldados na cidade?"}, - {TR_PARAMETER_PRODUCED, "Produzido?"}, + {TR_PARAMETER_IN_CITY_ONLY, "Contar apenas soldados na cidade"}, + {TR_PARAMETER_PRODUCED, "Produzido"}, {TR_PARAMETER_RADIUS, "Raio"}, - {TR_PARAMETER_RESPECT_SETTINGS, "Aceitar confirgurações de estoque?"}, - {TR_PARAMETER_SET_BUY_PRICE, "Definir preço de compra?"}, - {TR_PARAMETER_SET_TO_VALUE, "Definir como valor?"}, - {TR_PARAMETER_SHOW_MESSAGE, "Mostrar mensagem?"}, + {TR_PARAMETER_RESPECT_SETTINGS, "Aceitar confirgurações de estoque"}, + {TR_PARAMETER_SET_BUY_PRICE, "Definir preço de compra"}, + {TR_PARAMETER_SET_TO_VALUE, "Definir como valor"}, + {TR_PARAMETER_SHOW_MESSAGE, "Mostrar mensagem"}, {TR_PARAMETER_TYPE_ALLOWED_BUILDING, "Tipo de construção permissível"}, {TR_PARAMETER_TYPE_BOOLEAN, "Verdadeiro ou Falso"}, {TR_PARAMETER_TYPE_BUILDING_COUNTING, "Tipo de construção para soma"}, @@ -1172,7 +1172,7 @@ static translation_string all_strings[] = { {TR_PARAMETER_TYPE_ROUTE, "Apontar rota comercial"}, {TR_PARAMETER_TYPE_STANDARD_MESSAGE, "Mensagem padrão"}, {TR_PARAMETER_TYPE_STORAGE_TYPE, "Tipo de estoque"}, - {TR_PARAMETER_USE_PERCENTAGE, "Usar porcentagem?"}, + {TR_PARAMETER_USE_PERCENTAGE, "Usar porcentagem"}, {TR_PARAMETER_VALUE_BOOLEAN_FALSE, "Falso"}, {TR_PARAMETER_VALUE_BOOLEAN_TRUE, "Verdadeiro"}, {TR_PARAMETER_VALUE_BUILDING_LARGE_TEMPLE_CERES, "Templo grande de Ceres"}, diff --git a/src/translation/russian.c b/src/translation/russian.c index b5b353f793..6725ce954b 100644 --- a/src/translation/russian.c +++ b/src/translation/russian.c @@ -1142,23 +1142,23 @@ static translation_string all_strings[] = { {TR_PARAMETER_TYPE_ROUTE, "Целевой торговый путь"}, {TR_PARAMETER_TYPE_STANDARD_MESSAGE, "Стандартное сообщение"}, {TR_PARAMETER_TYPE_FUTURE_CITY, "Целевой будущий торговый город"}, - {TR_PARAMETER_USE_PERCENTAGE, "Использовать процент?"}, - {TR_PARAMETER_IN_CITY_ONLY, "Считать только солдат в городе?"}, - {TR_PARAMETER_CHECK_FOR_ONGOING, "Проверить, что он продолжается?"}, - {TR_PARAMETER_SHOW_MESSAGE, "Показать сообщение?"}, - {TR_PARAMETER_SET_TO_VALUE, "Установить на значение?"}, - {TR_PARAMETER_ADD_AS_BUYING, "Добавить в качестве покупки?"}, - {TR_PARAMETER_PRODUCED, "Производить?"}, - {TR_PARAMETER_ALLOWED, "Разрешить?"}, - {TR_PARAMETER_SET_BUY_PRICE, "Назначить цену покупки?"}, - {TR_PARAMETER_CHECK_FOR_OPEN, "Проверить, что путь открыт?"}, - {TR_PARAMETER_RESPECT_SETTINGS, "Соблюдать настройки хранения?"}, + {TR_PARAMETER_USE_PERCENTAGE, "Использовать процент"}, + {TR_PARAMETER_IN_CITY_ONLY, "Считать только солдат в городе"}, + {TR_PARAMETER_CHECK_FOR_ONGOING, "Проверить, что он продолжается"}, + {TR_PARAMETER_SHOW_MESSAGE, "Показать сообщение"}, + {TR_PARAMETER_SET_TO_VALUE, "Установить на значение"}, + {TR_PARAMETER_ADD_AS_BUYING, "Добавить в качестве покупки"}, + {TR_PARAMETER_PRODUCED, "Производить"}, + {TR_PARAMETER_ALLOWED, "Разрешить"}, + {TR_PARAMETER_SET_BUY_PRICE, "Назначить цену покупки"}, + {TR_PARAMETER_CHECK_FOR_OPEN, "Проверить, что путь открыт"}, + {TR_PARAMETER_RESPECT_SETTINGS, "Соблюдать настройки хранения"}, {TR_PARAMETER_TYPE_CUSTOM_MESSAGE, "Пользовательское сообщение"}, {TR_PARAMETER_TYPE_CUSTOM_VARIABLE, "Переменная"}, {TR_PARAMETER_TYPE_RATING_TYPE, "Тип рейтинга"}, {TR_PARAMETER_TYPE_STORAGE_TYPE, "Тип хранилища"}, - {TR_PARAMETER_APPLY_COST, "Применять открытую стоимость?"}, - {TR_PARAMETER_DESTROY_ALL, "Разрушить все типы?"}, + {TR_PARAMETER_APPLY_COST, "Применять открытую стоимость"}, + {TR_PARAMETER_DESTROY_ALL, "Разрушить все типы"}, {TR_PARAMETER_GRID_OFFSET, "Ячейка"}, {TR_PARAMETER_RADIUS, "Радиус"}, {TR_PARAMETER_TYPE_INVASION_SIZE, "Размер"}, diff --git a/src/translation/simplified_chinese.c b/src/translation/simplified_chinese.c index 00b77ddc53..e8149b4f33 100644 --- a/src/translation/simplified_chinese.c +++ b/src/translation/simplified_chinese.c @@ -1132,23 +1132,23 @@ static translation_string all_strings[] = { {TR_PARAMETER_TYPE_ROUTE, "Target trade route"}, {TR_PARAMETER_TYPE_STANDARD_MESSAGE, "Standard message"}, {TR_PARAMETER_TYPE_FUTURE_CITY, "Target future trade city"}, - {TR_PARAMETER_USE_PERCENTAGE, "Use percentage?"}, - {TR_PARAMETER_IN_CITY_ONLY, "Only count soldiers in the city?"}, - {TR_PARAMETER_CHECK_FOR_ONGOING, "Check that it is ongoing?"}, - {TR_PARAMETER_SHOW_MESSAGE, "Show message?"}, - {TR_PARAMETER_SET_TO_VALUE, "Set to value?"}, - {TR_PARAMETER_ADD_AS_BUYING, "Add as buying?"}, - {TR_PARAMETER_PRODUCED, "Produced?"}, - {TR_PARAMETER_ALLOWED, "Allowed?"}, - {TR_PARAMETER_SET_BUY_PRICE, "Set buy price?"}, - {TR_PARAMETER_CHECK_FOR_OPEN, "Check for route being open?"}, - {TR_PARAMETER_RESPECT_SETTINGS, "Respect storage settings?"}, + {TR_PARAMETER_USE_PERCENTAGE, "Use percentage"}, + {TR_PARAMETER_IN_CITY_ONLY, "Only count soldiers in the city"}, + {TR_PARAMETER_CHECK_FOR_ONGOING, "Check that it is ongoing"}, + {TR_PARAMETER_SHOW_MESSAGE, "Show message"}, + {TR_PARAMETER_SET_TO_VALUE, "Set to value"}, + {TR_PARAMETER_ADD_AS_BUYING, "Add as buying"}, + {TR_PARAMETER_PRODUCED, "Produced"}, + {TR_PARAMETER_ALLOWED, "Allowed"}, + {TR_PARAMETER_SET_BUY_PRICE, "Set buy price"}, + {TR_PARAMETER_CHECK_FOR_OPEN, "Check for route being open"}, + {TR_PARAMETER_RESPECT_SETTINGS, "Respect storage settings"}, {TR_PARAMETER_TYPE_CUSTOM_MESSAGE, "Custom message"}, {TR_PARAMETER_TYPE_CUSTOM_VARIABLE, "Custom variable"}, {TR_PARAMETER_TYPE_RATING_TYPE, "Rating type"}, {TR_PARAMETER_TYPE_STORAGE_TYPE, "Storage type"}, - {TR_PARAMETER_APPLY_COST, "Apply the open cost?"}, - {TR_PARAMETER_DESTROY_ALL, "Destroy all types?"}, + {TR_PARAMETER_APPLY_COST, "Apply the open cost"}, + {TR_PARAMETER_DESTROY_ALL, "Destroy all types"}, {TR_PARAMETER_GRID_OFFSET, "Grid offset"}, {TR_PARAMETER_RADIUS, "Radius"}, {TR_PARAMETER_TYPE_INVASION_SIZE, "Size"}, diff --git a/src/translation/spanish.c b/src/translation/spanish.c index 172b108546..f36e3a8860 100644 --- a/src/translation/spanish.c +++ b/src/translation/spanish.c @@ -1082,23 +1082,23 @@ static translation_string all_strings[] = { {TR_PARAMETER_TYPE_ROUTE, "Ruta comercial objetivo"}, {TR_PARAMETER_TYPE_STANDARD_MESSAGE, "Mensaje estándar"}, {TR_PARAMETER_TYPE_FUTURE_CITY, "Futura ciudad comercial objetivo"}, - {TR_PARAMETER_USE_PERCENTAGE, "¿Usar porcentaje?"}, - {TR_PARAMETER_IN_CITY_ONLY, "¿Sólo cuenta soldados en la ciudad?"}, - {TR_PARAMETER_CHECK_FOR_ONGOING, "¿Comprobar que está en curso?"}, - {TR_PARAMETER_SHOW_MESSAGE, "¿Mostrar mensaje?"}, - {TR_PARAMETER_SET_TO_VALUE, "¿Poner un valor?"}, - {TR_PARAMETER_ADD_AS_BUYING, "¿Añadir como compra?"}, - {TR_PARAMETER_PRODUCED, "¿Producido?"}, - {TR_PARAMETER_ALLOWED, "¿Permitido?"}, - {TR_PARAMETER_SET_BUY_PRICE, "¿Fijar precio de compra?"}, - {TR_PARAMETER_CHECK_FOR_OPEN, "¿Comprobar si la ruta está abierta?"}, - {TR_PARAMETER_RESPECT_SETTINGS, "¿Respetar la configuración de almacenamiento?"}, + {TR_PARAMETER_USE_PERCENTAGE, "Usar porcentaje"}, + {TR_PARAMETER_IN_CITY_ONLY, "Sólo cuenta soldados en la ciudad"}, + {TR_PARAMETER_CHECK_FOR_ONGOING, "Comprobar que está en curso"}, + {TR_PARAMETER_SHOW_MESSAGE, "Mostrar mensaje"}, + {TR_PARAMETER_SET_TO_VALUE, "Poner un valor"}, + {TR_PARAMETER_ADD_AS_BUYING, "Añadir como compra"}, + {TR_PARAMETER_PRODUCED, "Producido"}, + {TR_PARAMETER_ALLOWED, "Permitido"}, + {TR_PARAMETER_SET_BUY_PRICE, "Fijar precio de compra"}, + {TR_PARAMETER_CHECK_FOR_OPEN, "Comprobar si la ruta está abierta"}, + {TR_PARAMETER_RESPECT_SETTINGS, "Respetar la configuración de almacenamiento"}, {TR_PARAMETER_TYPE_CUSTOM_MESSAGE, "Mensaje personalizado"}, {TR_PARAMETER_TYPE_CUSTOM_VARIABLE, "Variable personalizada"}, {TR_PARAMETER_TYPE_RATING_TYPE, "Tipo de calificación"}, {TR_PARAMETER_TYPE_STORAGE_TYPE, "Tipo de almacenamiento"}, - {TR_PARAMETER_APPLY_COST, "¿Aplicar el coste de apertura?"}, - {TR_PARAMETER_DESTROY_ALL, "¿Destruir todos los tipos?"}, + {TR_PARAMETER_APPLY_COST, "Aplicar el coste de apertura"}, + {TR_PARAMETER_DESTROY_ALL, "Destruir todos los tipos"}, {TR_PARAMETER_GRID_OFFSET, "Compensación de cuadrícula"}, {TR_PARAMETER_RADIUS, "Radio"}, {TR_PARAMETER_TYPE_INVASION_SIZE, "Tamaño"}, diff --git a/src/translation/traditional_chinese.c b/src/translation/traditional_chinese.c index 9ff14f6d8e..685c7b66be 100644 --- a/src/translation/traditional_chinese.c +++ b/src/translation/traditional_chinese.c @@ -1135,23 +1135,23 @@ static translation_string all_strings[] = { {TR_PARAMETER_TYPE_ROUTE, "Target trade route"}, {TR_PARAMETER_TYPE_STANDARD_MESSAGE, "Standard message"}, {TR_PARAMETER_TYPE_FUTURE_CITY, "Target future trade city"}, - {TR_PARAMETER_USE_PERCENTAGE, "Use percentage?"}, - {TR_PARAMETER_IN_CITY_ONLY, "Only count soldiers in the city?"}, - {TR_PARAMETER_CHECK_FOR_ONGOING, "Check that it is ongoing?"}, - {TR_PARAMETER_SHOW_MESSAGE, "Show message?"}, - {TR_PARAMETER_SET_TO_VALUE, "Set to value?"}, - {TR_PARAMETER_ADD_AS_BUYING, "Add as buying?"}, - {TR_PARAMETER_PRODUCED, "Produced?"}, - {TR_PARAMETER_ALLOWED, "Allowed?"}, - {TR_PARAMETER_SET_BUY_PRICE, "Set buy price?"}, - {TR_PARAMETER_CHECK_FOR_OPEN, "Check for route being open?"}, - {TR_PARAMETER_RESPECT_SETTINGS, "Respect storage settings?"}, + {TR_PARAMETER_USE_PERCENTAGE, "Use percentage"}, + {TR_PARAMETER_IN_CITY_ONLY, "Only count soldiers in the city"}, + {TR_PARAMETER_CHECK_FOR_ONGOING, "Check that it is ongoing"}, + {TR_PARAMETER_SHOW_MESSAGE, "Show message"}, + {TR_PARAMETER_SET_TO_VALUE, "Set to value"}, + {TR_PARAMETER_ADD_AS_BUYING, "Add as buying"}, + {TR_PARAMETER_PRODUCED, "Produced"}, + {TR_PARAMETER_ALLOWED, "Allowed"}, + {TR_PARAMETER_SET_BUY_PRICE, "Set buy price"}, + {TR_PARAMETER_CHECK_FOR_OPEN, "Check for route being open"}, + {TR_PARAMETER_RESPECT_SETTINGS, "Respect storage settings"}, {TR_PARAMETER_TYPE_CUSTOM_MESSAGE, "Custom message"}, {TR_PARAMETER_TYPE_CUSTOM_VARIABLE, "Custom variable"}, {TR_PARAMETER_TYPE_RATING_TYPE, "Rating type"}, {TR_PARAMETER_TYPE_STORAGE_TYPE, "Storage type"}, - {TR_PARAMETER_APPLY_COST, "Apply the open cost?"}, - {TR_PARAMETER_DESTROY_ALL, "Destroy all types?"}, + {TR_PARAMETER_APPLY_COST, "Apply the open cost"}, + {TR_PARAMETER_DESTROY_ALL, "Destroy all types"}, {TR_PARAMETER_GRID_OFFSET, "Grid offset"}, {TR_PARAMETER_RADIUS, "Radius"}, {TR_PARAMETER_TYPE_INVASION_SIZE, "Size"}, diff --git a/src/translation/translation.h b/src/translation/translation.h index 5a1bbb6e2c..cded311b5e 100644 --- a/src/translation/translation.h +++ b/src/translation/translation.h @@ -1903,9 +1903,64 @@ typedef enum { TR_BUILDING_HOUSE_LARGE_PALACE, TR_BUILDING_HOUSE_LUXURY_PALACE, TR_CONFIG_UI_BUILD_SHOW_RESERVOIR_RANGES, + TR_ACTION_TYPE_CHANGE_HOUSE_MODEL_DATA, + TR_PARAMETER_DEVOLVE_DESIRABILITY, + TR_PARAMETER_EVOLVE_DESIRABILITY, + TR_PARAMETER_ENTERTAINMENT, + TR_PARAMETER_WATER, + TR_PARAMETER_RELIGION, + TR_PARAMETER_EDUCATION, + TR_PARAMETER_BARBER, + TR_PARAMETER_BATHHOUSE, + TR_PARAMETER_HEALTH, + TR_PARAMETER_FOOD_TYPES, + TR_PARAMETER_POTTERY, + TR_PARAMETER_FURNITURE, + TR_PARAMETER_OIL, + TR_PARAMETER_WINE, + TR_PARAMETER_PROSPERITY, + TR_PARAMETER_MAX_PEOPLE, + TR_PARAMETER_TAX_MULTIPLIER, + TR_PARAMETER_TYPE_HOUSING_TYPE, + TR_PARAMETER_BUILDING_MODEL_REST_CONFIRMATION, + TR_PARAMETER_HOUSE_MODEL_REST_CONFIRMATION, TR_CONFIG_GP_CH_ALWAYS_DESTROY_BRIDGES, TR_CONFIG_CATEGORY_MANAGEMENT_DESTRUCTION, TR_CHEAT_DESTROYED_BUILDING, + TR_EDITOR_HOUSE_MODEL_DEVOLVE_DESIRABILITY, // Order is important + TR_EDITOR_HOUSE_MODEL_EVOLVE_DESIRABILITY, // + TR_EDITOR_HOUSE_MODEL_ENTERTAINMENT, // + TR_EDITOR_HOUSE_MODEL_WATER, // + TR_EDITOR_HOUSE_MODEL_RELIGION, // + TR_EDITOR_HOUSE_MODEL_EDUCATION, // + TR_EDITOR_HOUSE_MODEL_BARBER, // + TR_EDITOR_HOUSE_MODEL_BATHHOUSE, // + TR_EDITOR_HOUSE_MODEL_HEALTH, // + TR_EDITOR_HOUSE_MODEL_FOOD_TYPES, // + TR_EDITOR_HOUSE_MODEL_POTTERY, // + TR_EDITOR_HOUSE_MODEL_FURNITURE, // + TR_EDITOR_HOUSE_MODEL_OIL, // + TR_EDITOR_HOUSE_MODEL_WINE, // + TR_EDITOR_HOUSE_MODEL_PROSPERITY, // + TR_EDITOR_HOUSE_MODEL_MAX_PEOPLE, // + TR_EDITOR_HOUSE_MODEL_TAX_MULTIPLIER, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_DEVOLVE_DESIRABILITY, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_EVOLVE_DESIRABILITY, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_ENTERTAINMENT, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_WATER, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_RELIGION, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_EDUCATION, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_BARBER, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_BATHHOUSE, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_HEALTH, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_FOOD_TYPES, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_POTTERY, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_FURNITURE, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_OIL, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_WINE, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_PROSPERITY, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_MAX_PEOPLE, // + TR_EDITOR_HOUSE_MODEL_EXPLANATION_TAX_MULTIPLIER, // TR_EMPIRE_TOOL_OUR_CITY, TR_EMPIRE_TOOL_TRADE_CITY, TR_EMPIRE_TOOL_ROMAN_CITY, @@ -1958,6 +2013,19 @@ typedef enum { TR_EMPIRE_MOVE_OBJECT, TR_CONFIG_UI_EMPIRE_CLICK_TO_DELETE, TR_PARAMETER_TERRAIN_RUBBLE, + TR_ACTION_TYPE_CHANGE_GOAL, + TR_PARAMETER_TYPE_WIN_CONDITION, + TR_SCENARIO_WIN_CONDITION_CULTURE, + TR_SCENARIO_WIN_CONDITION_PROSPERITY, + TR_SCENARIO_WIN_CONDITION_PEACE, + TR_SCENARIO_WIN_CONDITION_FAVOR, + TR_SCENARIO_WIN_CONDITION_LOOSING_TIME, + TR_SCENARIO_WIN_CONDITION_WINNING_TIME, + TR_SCENARIO_WIN_CONDITION_POPULATION, + TR_EDITOR_COPY, + TR_EDITOR_PASTE, + TR_EDITOR_SCENARIO_EVENTS_COPY_SELECTED, + TR_EDITOR_SCENARIO_EVENTS_PASTE_SELECTED, TR_EMPIRE_DRAW_TRADE_ROUTE, TR_CONFIG_UI_EMPIRE_CONFIRM_DELETE, TR_EMPIRE_TOGGLE_EDGES, diff --git a/src/widget/city_pause_menu.c b/src/widget/city_pause_menu.c index 77a830c189..625eff68b0 100644 --- a/src/widget/city_pause_menu.c +++ b/src/widget/city_pause_menu.c @@ -102,7 +102,6 @@ static void replay_map_confirmed(int confirmed, int checked) scenario_save_campaign_player_name(); window_mission_selection_show_again(); } - model_reset(); scenario_events_process_all(); } diff --git a/src/widget/input_box.h b/src/widget/input_box.h index 7d04dcb3ee..94678a46c3 100644 --- a/src/widget/input_box.h +++ b/src/widget/input_box.h @@ -9,7 +9,7 @@ #define INPUT_BOX_CHARS_ALPHA "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz " #define INPUT_BOX_CHARS_ALPHANUMERIC "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 " #define INPUT_BOX_CHARS_FILENAME "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-() " -#define INPUT_BOX_CHARS_FORMULAS "01234567890+-*/()[],{}" +#define INPUT_BOX_CHARS_FORMULAS "01234567890+-*/()[],{}^" #define INPUT_BOX_CHARS_ALL_SUPPORTED "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-()!\"\'*+,./:;=?[]_{} " typedef struct { diff --git a/src/widget/top_menu.c b/src/widget/top_menu.c index 303a82c63c..7bee0d6dec 100644 --- a/src/widget/top_menu.c +++ b/src/widget/top_menu.c @@ -894,7 +894,6 @@ static void replay_map_confirmed(int confirmed, int checked) scenario_save_campaign_player_name(); window_mission_selection_show_again(); } - model_reset(); scenario_events_process_all(); } diff --git a/src/window/editor/attributes.c b/src/window/editor/attributes.c index 7ba3c60cfd..3a0c31fffe 100644 --- a/src/window/editor/attributes.c +++ b/src/window/editor/attributes.c @@ -30,6 +30,7 @@ #include "window/editor/invasions.h" #include "window/editor/map.h" #include "window/editor/model_data.h" +#include "window/editor/house_model_data.h" #include "window/editor/price_changes.h" #include "window/editor/requests.h" #include "window/editor/scenario_events.h" @@ -57,6 +58,7 @@ static void button_delete_intro(const generic_button *button); static void button_change_victory(const generic_button *button); static void button_delete_victory(const generic_button *button); static void button_change_model_data(const generic_button *button); +static void button_change_house_model_data(const generic_button *button); static void button_return_to_city(const generic_button *button); static void button_change_climate(const generic_button *button); static void button_change_image(int forward, int param2); @@ -77,6 +79,7 @@ static generic_button buttons[] = { {470, 156, 250, 30, button_change_intro, button_delete_intro, 13}, {470, 196, 250, 30, button_change_victory, button_delete_victory, 14}, {470, 236, 250, 30, button_change_model_data, 0, 15}, + {470, 276, 250, 30, button_change_house_model_data, 0, 16}, {470, 436, 250, 30, button_return_to_city}, }; #define NUMBER_OF_BUTTONS (sizeof(buttons) / sizeof(generic_button)) @@ -199,12 +202,15 @@ static void draw_foreground(void) " ", 470, 205, FONT_NORMAL_BLACK, 0); lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_SCENARIO_DESELECT_VICTORY, 490, 205, 230, FONT_NORMAL_BLACK); } - + button_border_draw(470, 236, 250, 30, data.focus_button_id == 15); lang_text_draw_centered(CUSTOM_TRANSLATION, TR_ACTION_TYPE_CHANGE_MODEL_DATA, 470, 245, 250, FONT_NORMAL_BLACK); + button_border_draw(470, 276, 250, 30, data.focus_button_id == 16); + lang_text_draw_centered(CUSTOM_TRANSLATION, TR_ACTION_TYPE_CHANGE_HOUSE_MODEL_DATA, 470, 285, 250, FONT_NORMAL_BLACK); + if (!editor_is_active()) { - button_border_draw(470, 436, 250, 30, data.focus_button_id == 16); + button_border_draw(470, 436, 250, 30, data.focus_button_id == 17); lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_RETURN_TO_CITY, 470, 445, 250, FONT_NORMAL_BLACK); } @@ -344,6 +350,12 @@ static void button_change_model_data(const generic_button *button) window_model_data_show(); } +static void button_change_house_model_data(const generic_button *button) +{ + stop(); + window_house_model_data_show(); +} + static void button_return_to_city(const generic_button *button) { stop(); diff --git a/src/window/editor/edit_demand_change.c b/src/window/editor/edit_demand_change.c index 7246d1f1a9..0dcd1bbdf3 100644 --- a/src/window/editor/edit_demand_change.c +++ b/src/window/editor/edit_demand_change.c @@ -243,7 +243,7 @@ static void set_change_amount(int value) static void button_amount(const generic_button *button) { - window_numeric_input_show(0, 0, button, 3, 999, set_change_amount); + window_numeric_input_show(0, 0, button, 4, 9999, set_change_amount); } static void button_buying(const generic_button *button) diff --git a/src/window/editor/edit_price_change.c b/src/window/editor/edit_price_change.c index 47408a0800..7d47a927d0 100644 --- a/src/window/editor/edit_price_change.c +++ b/src/window/editor/edit_price_change.c @@ -159,7 +159,7 @@ static void set_amount(int value) static void button_amount(const generic_button *button) { - window_numeric_input_show(0, 0, button, 2, 99, set_amount); + window_numeric_input_show(0, 0, button, 4, 9999, set_amount); } static void button_delete(const generic_button *button) diff --git a/src/window/editor/edit_request.c b/src/window/editor/edit_request.c index f4f40155b1..7585ff911c 100644 --- a/src/window/editor/edit_request.c +++ b/src/window/editor/edit_request.c @@ -382,10 +382,10 @@ static void set_resource(int value) static void button_resource(const generic_button *button) { - static const uint8_t *resource_texts[RESOURCE_MAX + RESOURCE_TOTAL_SPECIAL]; + static const uint8_t *resource_texts[RESOURCE_ALL]; static int total_resources = 0; if (!total_resources) { - for (resource_type resource = RESOURCE_NONE; resource < RESOURCE_MAX + RESOURCE_TOTAL_SPECIAL; resource++) { + for (resource_type resource = RESOURCE_NONE; resource < RESOURCE_ALL; resource++) { if ((!resource_is_storable(resource) && resource < RESOURCE_MAX) || resource == RESOURCE_TROOPS) { continue; } diff --git a/src/window/editor/house_model_data.c b/src/window/editor/house_model_data.c new file mode 100644 index 0000000000..11316b2e98 --- /dev/null +++ b/src/window/editor/house_model_data.c @@ -0,0 +1,285 @@ +#include "house_model_data.h" + +#include "building/properties.h" +#include "building/type.h" +#include "core/lang.h" +#include "core/string.h" +#include "game/resource.h" +#include "graphics/font.h" +#include "graphics/button.h" +#include "graphics/generic_button.h" +#include "graphics/graphics.h" +#include "graphics/grid_box.h" +#include "graphics/lang_text.h" +#include "graphics/text.h" +#include "graphics/panel.h" +#include "graphics/window.h" +#include "input/input.h" +#include "translation/translation.h" +#include "window/editor/map.h" +#include "window/editor/attributes.h" +#include "window/file_dialog.h" +#include "window/numeric_input.h" +#include "window/popup_dialog.h" + +#include + +#define NO_SELECTION (unsigned int) -1 +#define NUM_DATA_BUTTONS (sizeof(data_buttons) / sizeof(generic_button)) + +static void button_edit_model_value(const generic_button *button); + +static void button_static_click(const generic_button *button); + +static void populate_list(void); +static void draw_model_item(const grid_box_item *item); +static void model_item_click(const grid_box_item *item); + + +static struct { + unsigned int total_items; + house_level items[HOUSE_MAX + 1]; + + unsigned int data_buttons_focus_id; + unsigned int static_buttons_focus_id; + unsigned int target_index; + house_model_data_type data_type; +} data; + +static generic_button data_buttons[] = { + {141, 2, 48, 20, button_edit_model_value, 0, MODEL_DEVOLVE_DESIRABILITY}, + {196, 2, 48, 20, button_edit_model_value, 0, MODEL_EVOLVE_DESIRABILITY}, + {251, 2, 48, 20, button_edit_model_value, 0, MODEL_ENTERTAINMENT}, + {306, 2, 48, 20, button_edit_model_value, 0, MODEL_WATER}, + {361, 2, 48, 20, button_edit_model_value, 0, MODEL_RELIGION}, + {416, 2, 48, 20, button_edit_model_value, 0, MODEL_EDUCATION}, + {471, 2, 48, 20, button_edit_model_value, 0, MODEL_BARBER}, + {526, 2, 48, 20, button_edit_model_value, 0, MODEL_BATHHOUSE}, + {581, 2, 48, 20, button_edit_model_value, 0, MODEL_HEALTH}, + {141, 30, 48, 20, button_edit_model_value, 0, MODEL_FOOD_TYPES}, + {196, 30, 48, 20, button_edit_model_value, 0, MODEL_POTTERY}, + {251, 30, 48, 20, button_edit_model_value, 0, MODEL_OIL}, + {306, 30, 48, 20, button_edit_model_value, 0, MODEL_FURNITURE}, + {361, 30, 48, 20, button_edit_model_value, 0, MODEL_WINE}, + {416, 30, 48, 20, button_edit_model_value, 0, MODEL_PROSPERITY}, + {471, 30, 48, 20, button_edit_model_value, 0, MODEL_MAX_PEOPLE}, + {526, 30, 48, 20, button_edit_model_value, 0, MODEL_TAX_MULTIPLIER} +}; +#define MAX_DATA_BUTTONS (sizeof(data_buttons) / sizeof(generic_button)) + +static generic_button static_buttons[] = { + {28, 25 * BLOCK_SIZE, 12 * BLOCK_SIZE, 24, button_static_click, 0, 0}, + {232, 25 * BLOCK_SIZE, 12 * BLOCK_SIZE, 24, button_static_click, 0, 1}, + {436, 25 * BLOCK_SIZE, 12 * BLOCK_SIZE, 24, button_static_click, 0, 2} +}; +#define NUM_STATIC_BUTTONS (sizeof(static_buttons) / sizeof(generic_button)) + +static grid_box_type model_buttons = { + .x = 25, + .y = 108, + .width = 42 * BLOCK_SIZE , + .height = 20 * BLOCK_SIZE, + .item_height = 56, + .item_margin.horizontal = 8, + .item_margin.vertical = 2, + .extend_to_hidden_scrollbar = 1, + .on_click = model_item_click, + .draw_item = draw_model_item, +}; + +static void init(void) +{ + data.target_index = NO_SELECTION; + populate_list(); + grid_box_init(&model_buttons, data.total_items); +} + +static void populate_list(void) +{ + data.total_items = 0; + while (data.total_items < HOUSE_MAX + 1) { + data.items[data.total_items] = data.total_items; + data.total_items++; + } +} + +static void reset_confirmed(int accepted, int checked) +{ + if (accepted) { + model_reset_houses(); + window_request_refresh(); + } +} + +static void button_static_click(const generic_button *button) +{ + switch (button->parameter1) { + case 0: + window_file_dialog_show(FILE_TYPE_MODEL_DATA, FILE_DIALOG_SAVE); + break; + case 1: + window_popup_dialog_show_confirmation(translation_for(TR_BUTTON_RESET_DEFAULTS), + translation_for(TR_PARAMETER_HOUSE_MODEL_REST_CONFIRMATION), NULL, reset_confirmed); + break; + case 2: + window_file_dialog_show(FILE_TYPE_MODEL_DATA, FILE_DIALOG_LOAD); + break; + default: + break; + } +} + +static void set_model_value(int value) +{ + model_house *model = model_get_house(data.items[data.target_index]); + *model_get_ptr_for_house_data_type(model, data.data_type) = value; + data.target_index = NO_SELECTION; +} + +static void button_edit_model_value(const generic_button *button) +{ + data.data_type = button->parameter1; + window_numeric_input_bound_show(model_buttons.focused_item.x, model_buttons.focused_item.y, button, 9, + model_get_min_for_house_data_type(data.data_type), model_get_max_for_house_data_type(data.data_type), set_model_value); +} + +static void model_item_click(const grid_box_item *item) +{ + data.target_index = item->index; +} + +static void draw_model_item(const grid_box_item *item) +{ + button_border_draw(item->x, item->y, item->width, item->height, 0); + int h_level = data.items[item->index]; + + const uint8_t *h_string = lang_get_building_type_string(h_level + 10); // Conversion from house_level to building_type + text_draw_multiline(h_string, item->x + 8, item->y + 8, 8 * BLOCK_SIZE, 0, FONT_NORMAL_BLACK, 0); + + for (unsigned int i = 0; i < MAX_DATA_BUTTONS; i++) { + button_border_draw(item->x + data_buttons[i].x, item->y + data_buttons[i].y, + data_buttons[i].width, data_buttons[i].height, item->is_focused && data.data_buttons_focus_id == i + 1); + + model_house *model = model_get_house(h_level); + int value = *model_get_ptr_for_house_data_type(model, i); + + text_draw_number(value, 0, NULL, item->x + data_buttons[i].x + 8, item->y + data_buttons[i].y + 6, + FONT_SMALL_PLAIN, 0); + } + +} + +static void draw_background(void) +{ + window_editor_map_draw_all(); + + graphics_in_dialog(); + + outer_panel_draw(16, 32, 45, 27); + lang_text_draw_centered(CUSTOM_TRANSLATION, TR_ACTION_TYPE_CHANGE_HOUSE_MODEL_DATA, 16, 42, 45 * BLOCK_SIZE, FONT_LARGE_BLACK); + lang_text_draw_centered(13, 3, 16, 27 * BLOCK_SIZE + 8, 45 * BLOCK_SIZE, FONT_NORMAL_BLACK); + + lang_text_draw_centered(CUSTOM_TRANSLATION, TR_PARAMETER_MODEL, 28, 85, 8 * BLOCK_SIZE, FONT_SMALL_PLAIN); + + for (int i = 0; i < NUM_DATA_BUTTONS; i++) { + int x = data_buttons[i].x + 35; + int y = i > 8 ? 95 : 75; + lang_text_draw_centered_without_bounds(CUSTOM_TRANSLATION, + TR_EDITOR_HOUSE_MODEL_DEVOLVE_DESIRABILITY + i, x, y, 30, FONT_SMALL_PLAIN); + } + + graphics_reset_dialog(); + + grid_box_request_refresh(&model_buttons); +} + +static void draw_foreground(void) +{ + graphics_in_dialog(); + + for (unsigned int i = 0; i < NUM_STATIC_BUTTONS; i++) { + button_border_draw(static_buttons[i].x, static_buttons[i].y, + static_buttons[i].width, static_buttons[i].height, data.static_buttons_focus_id == i + 1); + translation_key key; + switch (i) { + default: + case 0: + key = TR_EDITOR_SCENARIO_EVENTS_EXPORT; + break; + case 1: + key = TR_BUTTON_RESET_DEFAULTS; + break; + case 2: + key = TR_EDITOR_SCENARIO_EVENTS_IMPORT; + break; + } + lang_text_draw_centered(CUSTOM_TRANSLATION, key, + static_buttons[i].x, static_buttons[i].y + 6, static_buttons[i].width, FONT_NORMAL_BLACK); + } + + grid_box_draw(&model_buttons); + + graphics_reset_dialog(); +} + +static void handle_input(const mouse *m, const hotkeys *h) +{ + const mouse *m_dialog = mouse_in_dialog(m); + if (generic_buttons_handle_mouse(m_dialog, 0, 0, static_buttons, NUM_STATIC_BUTTONS, &data.static_buttons_focus_id)) { + return; + } + grid_box_handle_input(&model_buttons, m_dialog, 1); + + int x = 0, y = 0; + if (model_buttons.focused_item.is_focused) { + x = model_buttons.focused_item.x; + y = model_buttons.focused_item.y; + } + if (generic_buttons_handle_mouse(m_dialog, x, y, data_buttons, NUM_DATA_BUTTONS, &data.data_buttons_focus_id)) { + return; + } + + if (input_go_back_requested(m, h)) { + window_editor_attributes_show(); + } +} + +static int desirability_tooltip(tooltip_context *c) +{ + const mouse *m_global = mouse_get(); + const mouse *m = mouse_in_dialog(m_global); + + for (int i = 0; i < NUM_DATA_BUTTONS; i++) { + const uint8_t *text = translation_for(TR_EDITOR_HOUSE_MODEL_DEVOLVE_DESIRABILITY + i); + int width = text_get_width(text, FONT_SMALL_PLAIN); + int x = data_buttons[i].x + 35; + int y = i > 8 ? 95 : 75; + + if (x <= m->x && x + width > m->x && + y <= m->y && y + 10 > m->y) { + c->text_group = CUSTOM_TRANSLATION; + c->text_id = TR_EDITOR_HOUSE_MODEL_EXPLANATION_DEVOLVE_DESIRABILITY + i; + c->type = TOOLTIP_BUTTON; + return 1; + } + } + return 0; +} + +static void get_tooltip(tooltip_context *c) +{ + desirability_tooltip(c); +} + +void window_house_model_data_show(void) +{ + init(); + window_type window = { + WINDOW_EDITOR_MODEL_DATA, + draw_background, + draw_foreground, + handle_input, + get_tooltip + }; + window_show(&window); +} diff --git a/src/window/editor/house_model_data.h b/src/window/editor/house_model_data.h new file mode 100644 index 0000000000..d4e9c4c0ae --- /dev/null +++ b/src/window/editor/house_model_data.h @@ -0,0 +1,6 @@ +#ifndef WINDOW_HOUSE_MODEL_DATA_H +#define WINDOW_HOUSE_MODEL_DATA_H + +void window_house_model_data_show(void); + +#endif // WINDOW_HOUSE_MODEL_DATA_H diff --git a/src/window/editor/model_data.c b/src/window/editor/model_data.c index 513bcd3585..906e0ac576 100644 --- a/src/window/editor/model_data.c +++ b/src/window/editor/model_data.c @@ -18,21 +18,19 @@ #include "input/input.h" #include "translation/translation.h" #include "window/editor/map.h" +#include "window/editor/attributes.h" #include "window/file_dialog.h" #include "window/numeric_input.h" +#include "window/popup_dialog.h" #include #define NO_SELECTION (unsigned int) -1 -#define NUM_DATA_BUTTONS (sizeof(data_buttons) / sizeof(generic_button)) +#define UNLIMITED 1000000000 //fits in 32bit signed/unsigned int +#define NEGATIVE_UNLIMITED -1000000000 //fits in 32bit signed int -static void button_edit_cost(const generic_button *button); -static void button_edit_value(const generic_button *button); -static void button_edit_step(const generic_button *button); -static void button_edit_step_size(const generic_button *button); -static void button_edit_range(const generic_button *button); -static void button_edit_laborers(const generic_button *button); static void button_edit_production(const generic_button *button); +static void button_edit_model_value(const generic_button *button); static void button_static_click(const generic_button *button); @@ -42,7 +40,6 @@ static void model_item_click(const grid_box_item *item); static void building_tooltip(const grid_box_item *item, tooltip_context *c); - static struct { unsigned int total_items; building_type items[BUILDING_TYPE_MAX]; @@ -50,18 +47,20 @@ static struct { unsigned int data_buttons_focus_id; unsigned int static_buttons_focus_id; unsigned int target_index; + building_model_data_type data_type; } data; + static generic_button data_buttons[] = { - {200, 2, 48, 20, button_edit_cost}, - {260, 2, 48, 20, button_edit_value}, - {315, 2, 48, 20, button_edit_step}, - {370, 2, 48, 20, button_edit_step_size}, - {425, 2, 48, 20, button_edit_range}, - {480, 2, 48, 20, button_edit_laborers}, + {205, 2, 48, 20, button_edit_model_value, 0, MODEL_COST}, + {260, 2, 48, 20, button_edit_model_value, 0, MODEL_DESIRABILITY_VALUE}, + {315, 2, 48, 20, button_edit_model_value, 0, MODEL_DESIRABILITY_STEP}, + {370, 2, 48, 20, button_edit_model_value, 0, MODEL_DESIRABILITY_STEP_SIZE}, + {425, 2, 48, 20, button_edit_model_value, 0, MODEL_DESIRABILITY_RANGE}, + {480, 2, 48, 20, button_edit_model_value, 0, MODEL_LABORERS}, {535, 2, 48, 20, button_edit_production} }; -#define MAX_DATA_BUTTONS (sizeof(data_buttons) / sizeof(generic_button)) +#define NUM_DATA_BUTTONS (sizeof(data_buttons) / sizeof(generic_button)) static generic_button static_buttons[] = { {28, 25 * BLOCK_SIZE, 12 * BLOCK_SIZE, 24, button_static_click, 0, 0}, @@ -104,6 +103,21 @@ static void populate_list(void) } } +static int building_produces_resource(building_type type) +{ + return building_is_raw_resource_producer(type) || building_is_workshop(type) || type == BUILDING_WHARF + || building_is_farm(type) || type == BUILDING_CITY_MINT || type == BUILDING_BARRACKS; +} + +static void reset_confirmed(int accepted, int checked) +{ + if (accepted) { + model_reset_buildings(); + resource_init(); + window_request_refresh(); + } +} + static void button_static_click(const generic_button *button) { switch (button->parameter1) { @@ -111,9 +125,8 @@ static void button_static_click(const generic_button *button) window_file_dialog_show(FILE_TYPE_MODEL_DATA, FILE_DIALOG_SAVE); break; case 1: - model_reset(); - resource_init(); - window_request_refresh(); + window_popup_dialog_show_confirmation(translation_for(TR_BUTTON_RESET_DEFAULTS), + translation_for(TR_PARAMETER_BUILDING_MODEL_REST_CONFIRMATION), NULL, reset_confirmed); break; case 2: window_file_dialog_show(FILE_TYPE_MODEL_DATA, FILE_DIALOG_LOAD); @@ -123,82 +136,18 @@ static void button_static_click(const generic_button *button) } } -static void set_cost_value(int value) -{ - model_building *model = model_get_building(data.items[data.target_index]); - model->cost = value; - data.target_index = NO_SELECTION; -} - -static void button_edit_cost(const generic_button *button) -{ - window_numeric_input_bound_show(model_buttons.focused_item.x, model_buttons.focused_item.y, button, - 9, -1000000000, 1000000000, set_cost_value); -} - -static void set_desirability_value(int value) -{ - model_building *model = model_get_building(data.items[data.target_index]); - model->desirability_value = value; - data.target_index = NO_SELECTION; -} - -static void button_edit_value(const generic_button *button) -{ - window_numeric_input_bound_show(model_buttons.focused_item.x, model_buttons.focused_item.y, button, - 9, -1000000000, 1000000000, set_desirability_value); -} - -static void set_desirability_step(int value) -{ - model_building *model = model_get_building(data.items[data.target_index]); - model->desirability_step = value; - data.target_index = NO_SELECTION; -} - -static void button_edit_step(const generic_button *button) -{ - window_numeric_input_bound_show(model_buttons.focused_item.x, model_buttons.focused_item.y, button, - 9, -1000000000, 1000000000, set_desirability_step); -} - -static void set_desirability_step_size(int value) +static void set_model_value(int value) { model_building *model = model_get_building(data.items[data.target_index]); - model->desirability_step_size = value; + *model_get_ptr_for_building_data_type(model, data.data_type) = value; data.target_index = NO_SELECTION; } -static void button_edit_step_size(const generic_button *button) +static void button_edit_model_value(const generic_button *button) { - window_numeric_input_bound_show(model_buttons.focused_item.x, model_buttons.focused_item.y, button, - 9, -1000000000, 1000000000, set_desirability_step_size); -} - -static void set_desirability_range(int value) -{ - model_building *model = model_get_building(data.items[data.target_index]); - model->desirability_range = value; - data.target_index = NO_SELECTION; -} - -static void button_edit_range(const generic_button *button) -{ - window_numeric_input_bound_show(model_buttons.focused_item.x, model_buttons.focused_item.y, button, - 9, -1000000000, 1000000000, set_desirability_range); -} - -static void set_laborers(int value) -{ - model_building *model = model_get_building(data.items[data.target_index]); - model->laborers = value; - data.target_index = NO_SELECTION; -} - -static void button_edit_laborers(const generic_button *button) -{ - window_numeric_input_bound_show(model_buttons.focused_item.x, model_buttons.focused_item.y, button, - 9, -1000000000, 1000000000, set_laborers); + data.data_type = button->parameter1; + window_numeric_input_bound_show(model_buttons.focused_item.x, model_buttons.focused_item.y, button, 9, + model_get_min_for_data_type(data.data_type), model_get_max_for_data_type(data.data_type), set_model_value); } static void set_production(int value) @@ -211,9 +160,9 @@ static void set_production(int value) static void button_edit_production(const generic_button *button) { building_type type = data.items[data.target_index]; - if (building_is_raw_resource_producer(type) || building_is_workshop(type) || type == BUILDING_WHARF || building_is_farm(type)) { + if (building_produces_resource(type)) { window_numeric_input_bound_show(model_buttons.focused_item.x, model_buttons.focused_item.y, button, - 9, -1000000000, 1000000000, set_production); + 9, NEGATIVE_UNLIMITED, UNLIMITED, set_production); } } @@ -224,17 +173,10 @@ static void model_item_click(const grid_box_item *item) static void get_building_translation(building_type b_type, uint8_t *buffer, int buffer_size) { - const uint8_t *b_type_string = lang_get_building_type_string(b_type); - - if (BUILDING_SMALL_TEMPLE_CERES <= b_type && b_type <= BUILDING_SMALL_TEMPLE_VENUS) { - const uint8_t *temple_prefix = lang_get_building_type_string(BUILDING_MENU_SMALL_TEMPLES); - snprintf((char *) buffer, buffer_size, "%s %s", temple_prefix, b_type_string); - } else if (BUILDING_LARGE_TEMPLE_CERES <= b_type && b_type <= BUILDING_LARGE_TEMPLE_VENUS) { - const uint8_t *temple_prefix = lang_get_building_type_string(BUILDING_MENU_LARGE_TEMPLES); - snprintf((char *) buffer, buffer_size, "%s %s", temple_prefix, b_type_string); - } else { - string_copy(b_type_string, buffer, buffer_size); - } + const building_properties *props = building_properties_for_type(b_type); + const uint8_t *b_type_string = props->event_data.key ? translation_for(props->event_data.key) : lang_get_building_type_string(b_type); + + string_copy(b_type_string, buffer, buffer_size); } static void draw_model_item(const grid_box_item *item) @@ -246,32 +188,18 @@ static void draw_model_item(const grid_box_item *item) get_building_translation(b_type, b_string, sizeof(b_string)); text_draw_ellipsized(b_string, item->x + 8, item->y + 8, 12 * BLOCK_SIZE, FONT_NORMAL_BLACK, 0); - for (unsigned int i = 0; i < MAX_DATA_BUTTONS - (!(building_is_raw_resource_producer(b_type) || - building_is_workshop(b_type) || b_type == BUILDING_WHARF || building_is_farm(b_type))); i++) { + for (unsigned int i = 0; i < NUM_DATA_BUTTONS - !building_produces_resource(b_type); i++) { button_border_draw(item->x + data_buttons[i].x, item->y + data_buttons[i].y, data_buttons[i].width, data_buttons[i].height, item->is_focused && data.data_buttons_focus_id == i + 1); - int value = 0; - switch (i) { - case 0: - value = model_get_building(b_type)->cost; break; - case 1: - value = model_get_building(b_type)->desirability_value; break; - case 2: - value = model_get_building(b_type)->desirability_step; break; - case 3: - value = model_get_building(b_type)->desirability_step_size; break; - case 4: - value = model_get_building(b_type)->desirability_range; break; - case 5: - value = model_get_building(b_type)->laborers; break; - case 6: - value = resource_get_data(resource_get_from_industry(b_type))->production_per_month; + model_building *model = model_get_building(b_type); + int value = *model_get_ptr_for_building_data_type(model, i); + if (i == 6) { + value = resource_get_data(resource_get_from_industry(b_type))->production_per_month; } text_draw_number(value, 0, NULL, item->x + data_buttons[i].x + 8, item->y + data_buttons[i].y + 6, FONT_SMALL_PLAIN, 0); } - } static void draw_background(void) @@ -285,13 +213,13 @@ static void draw_background(void) lang_text_draw_centered(13, 3, 16, 27 * BLOCK_SIZE + 8, 42 * BLOCK_SIZE, FONT_NORMAL_BLACK); lang_text_draw_centered(CUSTOM_TRANSLATION, TR_PARAMETER_MODEL, 80, 75, 30, FONT_SMALL_PLAIN); - lang_text_draw_centered(CUSTOM_TRANSLATION, TR_PARAMETER_COST, 235, 75, 30, FONT_SMALL_PLAIN); - lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_MODEL_DATA_DES_VALUE, 295, 75, 30, FONT_SMALL_PLAIN); - lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_MODEL_DATA_DES_STEP, 350, 75, 30, FONT_SMALL_PLAIN); - lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_MODEL_DATA_DES_STEP_SIZE, 405, 75, 30, FONT_SMALL_PLAIN); - lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_MODEL_DATA_DES_RANGE, 460, 75, 30, FONT_SMALL_PLAIN); - lang_text_draw_centered(CUSTOM_TRANSLATION, TR_PARAMETER_LABORERS, 505, 75, 30, FONT_SMALL_PLAIN); - lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_MODEL_PRODUCTION, 570, 75, 30, FONT_SMALL_PLAIN); + lang_text_draw_centered_without_bounds(CUSTOM_TRANSLATION, TR_PARAMETER_COST, data_buttons[0].x + 35, 75, 30, FONT_SMALL_PLAIN); + lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_MODEL_DATA_DES_VALUE, data_buttons[1].x + 35, 75, 30, FONT_SMALL_PLAIN); + lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_MODEL_DATA_DES_STEP, data_buttons[2].x + 35, 75, 30, FONT_SMALL_PLAIN); + lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_MODEL_DATA_DES_STEP_SIZE, data_buttons[3].x + 35, 75, 30, FONT_SMALL_PLAIN); + lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_MODEL_DATA_DES_RANGE, data_buttons[4].x + 35, 75, 30, FONT_SMALL_PLAIN); + lang_text_draw_centered_without_bounds(CUSTOM_TRANSLATION, TR_PARAMETER_LABORERS, data_buttons[5].x + 35, 75, 30, FONT_SMALL_PLAIN); + lang_text_draw_centered_without_bounds(CUSTOM_TRANSLATION, TR_EDITOR_MODEL_PRODUCTION, data_buttons[6].x + 35, 75, 30, FONT_SMALL_PLAIN); graphics_reset_dialog(); @@ -345,7 +273,7 @@ static void handle_input(const mouse *m, const hotkeys *h) } if (input_go_back_requested(m, h)) { - window_go_back(); + window_editor_attributes_show(); } } @@ -357,23 +285,7 @@ static int desirability_tooltip(tooltip_context *c) for (int i = 0; i < 4; i++) { const uint8_t *text = translation_for(TR_EDITOR_MODEL_DATA_DES_VALUE + i); int width = text_get_width(text, FONT_SMALL_PLAIN); - int x; - - switch (i) { - default: - case 0: - x = 295; - break; - case 1: - x = 350; - break; - case 2: - x = 405; - break; - case 3: - x = 460; - break; - } + int x = data_buttons[i + 1].x + 35; if (x <= m->x && x + width > m->x && 75 <= m->y && 75 + 10 > m->y) { @@ -388,9 +300,9 @@ static int desirability_tooltip(tooltip_context *c) static void building_tooltip(const grid_box_item *item, tooltip_context *c) { - uint8_t *text; - text = (uint8_t *) lang_get_building_type_string(data.items[item->index]); - if (text_get_width(text, FONT_SMALL_PLAIN) > 12 * BLOCK_SIZE - 32 && !data.data_buttons_focus_id) { + uint8_t text[128]; + get_building_translation(data.items[item->index], text, 128); + if (text_get_width(text, FONT_SMALL_PLAIN) > 12 * BLOCK_SIZE + 5 - 32 && !data.data_buttons_focus_id) { c->precomposed_text = text; c->type = TOOLTIP_BUTTON; } diff --git a/src/window/editor/scenario_action_edit.c b/src/window/editor/scenario_action_edit.c index ca4fc8a033..a9e4725568 100644 --- a/src/window/editor/scenario_action_edit.c +++ b/src/window/editor/scenario_action_edit.c @@ -1,5 +1,6 @@ #include "scenario_action_edit.h" +#include "building/properties.h" #include "core/string.h" #include "editor/tool.h" #include "game/resource.h" @@ -13,6 +14,7 @@ #include "graphics/window.h" #include "input/input.h" #include "map/grid.h" +#include "scenario/criteria.h" #include "scenario/event/action_handler.h" #include "scenario/event/controller.h" #include "scenario/event/formula.h" @@ -376,6 +378,16 @@ static void resource_selection(const generic_button *button) resource_texts, RESOURCE_MAX - 1, set_resource_value); } +static void all_resource_selection(const generic_button *button) +{ + static const uint8_t *resource_texts[RESOURCE_ALL]; + for (resource_type resource = RESOURCE_MIN; resource < RESOURCE_ALL; resource++) { + resource_texts[resource - 1] = resource_get_data(resource)->text; + } + window_select_list_show_text(screen_dialog_offset_x(), screen_dialog_offset_y(), button, + resource_texts, RESOURCE_ALL - 1, set_resource_value); +} + static void custom_message_selection(void) { window_editor_select_custom_message_show(set_param_value); @@ -443,6 +455,17 @@ static void create_evaluation_formula(xml_data_attribute_t *parameter) int current_index = get_param_value(); data.formula_min_limit = parameter->min_limit; data.formula_max_limit = parameter->max_limit; + if (data.action->type == ACTION_TYPE_CHANGE_MODEL_DATA) { + data.formula_min_limit = model_get_min_for_data_type(data.action->parameter2); + data.formula_max_limit = model_get_max_for_data_type(data.action->parameter2); + } + if (data.action->type == ACTION_TYPE_CHANGE_HOUSE_MODEL_DATA) { + data.formula_min_limit = model_get_min_for_house_data_type(data.action->parameter2); + data.formula_max_limit = model_get_max_for_house_data_type(data.action->parameter2); + } + if (data.action->type == ACTION_TYPE_CHANGE_GOAL) { + data.formula_max_limit = scenario_criteria_get_max_value(data.action->parameter1); + } if (current_index > 0) { // a formula already exists const uint8_t *src = scenario_formula_get_string((unsigned int) current_index); if (src) { @@ -551,6 +574,7 @@ static void change_parameter(xml_data_attribute_t *parameter, const generic_butt case PARAMETER_TYPE_CLIMATE: case PARAMETER_TYPE_TERRAIN: case PARAMETER_TYPE_DATA_TYPE: + case PARAMETER_TYPE_HOUSE_DATA_TYPE: case PARAMETER_TYPE_MODEL: case PARAMETER_TYPE_CITY_PROPERTY: case PARAMETER_TYPE_PERCENTAGE: @@ -560,6 +584,7 @@ static void change_parameter(xml_data_attribute_t *parameter, const generic_butt case PARAMETER_TYPE_ENEMY_CLASS: case PARAMETER_TYPE_COVERAGE_BUILDINGS: case PARAMETER_TYPE_RANK: + case PARAMETER_TYPE_WIN_CONDITION: window_editor_select_special_attribute_mapping_show(parameter->type, set_param_value, data.parameter_being_edited_current_value); return; case PARAMETER_TYPE_ALLOWED_BUILDING: @@ -591,10 +616,11 @@ static void change_parameter(xml_data_attribute_t *parameter, const generic_butt window_editor_select_city_resources_for_route_show(set_param_value, data.action->parameter3); return; case PARAMETER_TYPE_GRID_SLICE: - { start_grid_slice_selection(); return; - } + case PARAMETER_TYPE_RESOURCE_ALL: + all_resource_selection(button); + return; default: return; } diff --git a/src/window/editor/scenario_event_details.c b/src/window/editor/scenario_event_details.c index 42f06bc334..e127fbe590 100644 --- a/src/window/editor/scenario_event_details.c +++ b/src/window/editor/scenario_event_details.c @@ -1,6 +1,7 @@ #include "scenario_event_details.h" #include "assets/assets.h" +#include "core/array.h" #include "core/lang.h" #include "core/log.h" #include "core/string.h" @@ -18,6 +19,7 @@ #include "input/input.h" #include "scenario/event/event.h" #include "scenario/event/controller.h" +#include "scenario/event/data.h" #include "scenario/event/parameter_data.h" #include "widget/dropdown_button.h" #include "widget/input_box.h" @@ -73,9 +75,13 @@ typedef enum { } checkbox_selection_type; static void button_add_new_condition(const generic_button *button); -static void button_delete_selected(const generic_button *button); static void button_add_new_action(const generic_button *button); +static void button_copy_selected(const generic_button *button); +static void button_delete_selected(const generic_button *button); +static void button_paste_selected(const generic_button *button); static void button_delete_event(const generic_button *button); +static void button_copy_event(const generic_button *button); +static void button_paste_event(const generic_button *button); static void button_repeat_type(const generic_button *button); static void button_repeat_times(const generic_button *button); static void button_repeat_between(const generic_button *button); @@ -101,6 +107,11 @@ typedef struct { static struct { uint8_t event_name[EVENT_NAME_LENGTH]; scenario_event_t *event; + scenario_event_t copied_event; + int did_copy_event; + array(scenario_condition_group_t) copied_condition_groups; + array(scenario_action_t) copied_actions; + int did_copy_selected; int repeat_type; struct { condition_list_item *list; @@ -137,7 +148,7 @@ static grid_box_type conditions_grid_box = { .x = 16, .y = 188, .width = 18 * BLOCK_SIZE, - .height = 13 * BLOCK_SIZE + 2, + .height = 12 * BLOCK_SIZE - 2, .num_columns = 1, .item_height = 30, .item_margin.horizontal = 10, @@ -152,7 +163,7 @@ static grid_box_type actions_grid_box = { .x = 320, .y = 188, .width = 18 * BLOCK_SIZE, - .height = 13 * BLOCK_SIZE + 2, + .height = 12 * BLOCK_SIZE - 2, .num_columns = 1, .item_height = 30, .item_margin.horizontal = 10, @@ -185,10 +196,14 @@ static dropdown_button repeat_interval_dropdown; #define NUM_BOTTOM_BUTTONS (sizeof(bottom_buttons) / sizeof(generic_button)) static generic_button bottom_buttons[] = { - {16, 409, 192, 25, button_add_new_condition}, + {16, 379, 192, 25, button_add_new_condition}, + {432, 379, 192, 25, button_add_new_action}, + {16, 409, 192, 25, button_copy_selected}, {224, 409, 192, 25, button_delete_selected, 0, 0, DISABLE_ON_NO_SELECTION}, - {432, 409, 192, 25, button_add_new_action}, - {16, 439, 200, 25, button_delete_event}, + {432, 409, 192, 25, button_paste_selected}, + {16, 439, 192, 25, button_delete_event}, + {224, 439, 134, 25, button_copy_event}, + {374, 439, 134, 25, button_paste_event}, {524, 439, 100, 25, button_ok}, }; @@ -545,24 +560,32 @@ static void draw_background(void) y_offset, actions_grid_box.width, FONT_NORMAL_BLACK); } - // New condition button label + // New action and condition buttons lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_SCENARIO_CONDITION_ADD, bottom_buttons[0].x, bottom_buttons[0].y + 6, bottom_buttons[0].width, FONT_NORMAL_BLACK); + lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_SCENARIO_ACTION_ADD, + bottom_buttons[1].x, bottom_buttons[1].y + 6, bottom_buttons[1].width, FONT_NORMAL_BLACK); - // Delete selected button label - color = data.conditions.selection_type == CHECKBOX_NO_SELECTION && + // Selected operation buttons + color_t color_copy = data.conditions.selection_type == CHECKBOX_NO_SELECTION && + data.actions.selection_type == CHECKBOX_NO_SELECTION ? COLOR_FONT_LIGHT_GRAY : 0; + color_t color_delete = data.conditions.selection_type == CHECKBOX_NO_SELECTION && data.actions.selection_type == CHECKBOX_NO_SELECTION ? COLOR_FONT_LIGHT_GRAY : COLOR_RED; + lang_text_draw_centered_colored(CUSTOM_TRANSLATION, TR_EDITOR_SCENARIO_EVENTS_COPY_SELECTED, + bottom_buttons[2].x, bottom_buttons[2].y + 6, bottom_buttons[2].width, FONT_NORMAL_PLAIN, color_delete); lang_text_draw_centered_colored(CUSTOM_TRANSLATION, TR_EDITOR_SCENARIO_EVENTS_DELETE_SELECTED, - bottom_buttons[1].x, bottom_buttons[1].y + 6, bottom_buttons[1].width, FONT_NORMAL_PLAIN, color); - - // Add action button label - lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_SCENARIO_ACTION_ADD, - bottom_buttons[2].x, bottom_buttons[2].y + 6, bottom_buttons[2].width, FONT_NORMAL_BLACK); + bottom_buttons[3].x, bottom_buttons[3].y + 6, bottom_buttons[3].width, FONT_NORMAL_PLAIN, color_delete); + lang_text_draw_centered_colored(CUSTOM_TRANSLATION, TR_EDITOR_SCENARIO_EVENTS_PASTE_SELECTED, + bottom_buttons[4].x, bottom_buttons[4].y + 6, bottom_buttons[4].width, FONT_NORMAL_PLAIN, color_delete); // Bottom buttons - lang_text_draw_centered_colored(CUSTOM_TRANSLATION, TR_EDITOR_DELETE, bottom_buttons[3].x, bottom_buttons[3].y + 6, - bottom_buttons[3].width, FONT_NORMAL_PLAIN, COLOR_RED); - lang_text_draw_centered(18, 3, bottom_buttons[4].x, bottom_buttons[4].y + 6, bottom_buttons[4].width, + lang_text_draw_centered_colored(CUSTOM_TRANSLATION, TR_EDITOR_DELETE, bottom_buttons[5].x, bottom_buttons[5].y + 6, + bottom_buttons[5].width, FONT_NORMAL_PLAIN, COLOR_RED); + lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_COPY, bottom_buttons[6].x, bottom_buttons[6].y + 6, + bottom_buttons[6].width, FONT_NORMAL_BLACK); + lang_text_draw_centered(CUSTOM_TRANSLATION, TR_EDITOR_PASTE, bottom_buttons[7].x, bottom_buttons[7].y + 6, + bottom_buttons[7].width, FONT_NORMAL_BLACK); + lang_text_draw_centered(18, 3, bottom_buttons[8].x, bottom_buttons[8].y + 6, bottom_buttons[8].width, FONT_NORMAL_BLACK); graphics_reset_dialog(); @@ -591,7 +614,8 @@ static void draw_condition_button(const grid_box_item *item) const scenario_condition_t *condition = data.conditions.list[item->index].condition; uint8_t text[MAX_TEXT_LENGTH]; - scenario_events_parameter_data_get_display_string_for_condition(condition, text, MAX_TEXT_LENGTH); + scenario_condition_data_t *xml_info = scenario_events_parameter_data_get_conditions_xml_attributes(condition->type); + string_copy(translation_for(xml_info->xml_attr.key), text, MAX_TEXT_LENGTH); if (text_get_width(text, FONT_NORMAL_BLACK) > item->width - 32) { text_draw_ellipsized(text, item->x + 28, item->y + 7, item->width - 32, FONT_NORMAL_BLACK, 0); } else { @@ -615,7 +639,8 @@ static void draw_action_button(const grid_box_item *item) button_border_draw(item->x + 24, item->y, item->width - 24, item->height, item->is_focused && item->mouse.x >= 24); const scenario_action_t *action = data.actions.list[item->index]; uint8_t text[MAX_TEXT_LENGTH]; - scenario_events_parameter_data_get_display_string_for_action(action, text, MAX_TEXT_LENGTH); + scenario_action_data_t *xml_info = scenario_events_parameter_data_get_actions_xml_attributes(action->type); + string_copy(translation_for(xml_info->xml_attr.key), text, MAX_TEXT_LENGTH); if (text_get_width(text, FONT_NORMAL_BLACK) > item->width - 32) { text_draw_ellipsized(text, item->x + 28, item->y + 7, item->width - 32, FONT_NORMAL_BLACK, 0); } else { @@ -943,6 +968,176 @@ static void button_delete_event(const generic_button *button) window_go_back(); } +static void copy_formulas_action(scenario_action_t *action, int **params, int index) +{ + int *param_value = params[index - 1]; + parameter_type p_type = scenario_events_parameter_data_get_action_parameter_type( + action->type, index, NULL, NULL); + if (p_type == PARAMETER_TYPE_FORMULA || p_type == PARAMETER_TYPE_GRID_SLICE) { + scenario_formula_t *formula = scenario_formula_get(*param_value); + if (!formula) { + return; + } + unsigned int id = scenario_formula_add(scenario_formula_get_string(*param_value), + formula->min_evaluation, formula->max_evaluation); + *param_value = id; + } +} + +static void copy_formulas_condition(scenario_condition_t *condition, int **params, int index) +{ + int *param_value = params[index - 1]; + parameter_type p_type = scenario_events_parameter_data_get_condition_parameter_type( + condition->type, index, NULL, NULL); + if (p_type == PARAMETER_TYPE_FORMULA || p_type == PARAMETER_TYPE_GRID_SLICE) { + scenario_formula_t *formula = scenario_formula_get(*param_value); + if (!formula) { + return; + } + unsigned int id = scenario_formula_add(scenario_formula_get_string(*param_value), + formula->min_evaluation, formula->max_evaluation); + *param_value = id; + } +} + +static void button_copy_selected(const generic_button *button) +{ + array_init(data.copied_actions, SCENARIO_ACTIONS_ARRAY_SIZE_STEP, data.event->actions.constructor, + data.event->actions.in_use); + array_init(data.copied_condition_groups, SCENARIO_CONDITION_GROUPS_ARRAY_SIZE_STEP, + data.event->condition_groups.constructor, data.event->condition_groups.in_use); + for (unsigned int i = 0; i < data.event->actions.size; i++) { + if (!data.actions.selected[i]) { + continue; + } + scenario_action_t *action; + array_new_item(data.copied_actions, action); + *action = *array_item(data.event->actions, i); + + scenario_parameters_foreach_in_action(action, copy_formulas_action); + } + + for (unsigned int i = 0; i < data.event->condition_groups.size; i++) { + scenario_condition_group_t *group; + array_new_item(data.copied_event.condition_groups, group); + scenario_condition_group_t *original_group = array_item(data.event->condition_groups, i); + group->type = original_group->type; + array_init(group->conditions, SCENARIO_CONDITIONS_ARRAY_SIZE_STEP, original_group->conditions.constructor, + original_group->conditions.in_use); + for (unsigned int j = 0; j < original_group->conditions.size; j++) { + scenario_condition_t *condition; + array_new_item(group->conditions, condition); + *condition = *array_item(original_group->conditions, j); + + scenario_parameters_foreach_in_condition(condition, copy_formulas_condition); + } + } + data.did_copy_selected = 1; +} + +static void button_paste_selected(const generic_button *button) +{ + if (!data.did_copy_selected) { + return; + } + + for (unsigned int i = 0; i < data.copied_actions.size; i++) { + scenario_action_t *action; + array_new_item(data.event->actions, action); + *action = *array_item(data.copied_actions, i); + + scenario_parameters_foreach_in_action(action, copy_formulas_action); + } + +} + +static void button_copy_event(const generic_button *button) +{ + data.copied_event.state = data.event->state; + data.copied_event.repeat_days_min = data.event->repeat_days_min; + data.copied_event.repeat_days_max = data.event->repeat_days_max; + data.copied_event.repeat_interval = data.event->repeat_interval; + data.copied_event.max_number_of_repeats = data.event->max_number_of_repeats; + data.copied_event.execution_count = data.event->execution_count; + data.copied_event.days_until_active = data.event->days_until_active; + string_copy(data.event->name, data.copied_event.name, EVENT_NAME_LENGTH); + array_init(data.copied_event.actions, SCENARIO_ACTIONS_ARRAY_SIZE_STEP, data.event->actions.constructor, + data.event->actions.in_use); + array_init(data.copied_event.condition_groups, SCENARIO_CONDITION_GROUPS_ARRAY_SIZE_STEP, + data.event->condition_groups.constructor, data.event->condition_groups.in_use); + for (unsigned int i = 0; i < data.event->actions.size; i++) { + scenario_action_t *action; + array_new_item(data.copied_event.actions, action); + *action = *array_item(data.event->actions, i); + + scenario_parameters_foreach_in_action(action, copy_formulas_action); + } + + for (unsigned int i = 0; i < data.event->condition_groups.size; i++) { + scenario_condition_group_t *group; + array_new_item(data.copied_event.condition_groups, group); + scenario_condition_group_t *original_group = array_item(data.event->condition_groups, i); + group->type = original_group->type; + array_init(group->conditions, SCENARIO_CONDITIONS_ARRAY_SIZE_STEP, original_group->conditions.constructor, + original_group->conditions.in_use); + for (unsigned int j = 0; j < original_group->conditions.size; j++) { + scenario_condition_t *condition; + array_new_item(group->conditions, condition); + *condition = *array_item(original_group->conditions, j); + + scenario_parameters_foreach_in_condition(condition, copy_formulas_condition); + } + } + data.did_copy_event = 1; +} + +static void button_paste_event(const generic_button *button) +{ + if (!data.did_copy_event) { + return; + } + int event_id = data.event->id; + data.event->state = data.copied_event.state; + data.event->repeat_days_min = data.copied_event.repeat_days_min; + data.event->repeat_days_max = data.copied_event.repeat_days_max; + data.event->repeat_interval = data.copied_event.repeat_interval; + data.event->max_number_of_repeats = data.copied_event.max_number_of_repeats; + data.event->execution_count = data.copied_event.execution_count; + data.event->days_until_active = data.copied_event.days_until_active; + string_copy(data.copied_event.name, data.event->name, EVENT_NAME_LENGTH); + array_init(data.event->actions, SCENARIO_ACTIONS_ARRAY_SIZE_STEP, data.copied_event.actions.constructor, + data.copied_event.actions.in_use); + array_init(data.event->condition_groups, SCENARIO_CONDITION_GROUPS_ARRAY_SIZE_STEP, + data.copied_event.condition_groups.constructor, data.copied_event.condition_groups.in_use); + for (unsigned int i = 0; i < data.copied_event.actions.size; i++) { + scenario_action_t *action; + array_new_item(data.event->actions, action); + *action = *array_item(data.copied_event.actions, i); + + scenario_parameters_foreach_in_action(action, copy_formulas_action); + } + + for (unsigned int i = 0; i < data.copied_event.condition_groups.size; i++) { + scenario_condition_group_t *group; + array_new_item(data.event->condition_groups, group); + scenario_condition_group_t *original_group = array_item(data.copied_event.condition_groups, i); + group->type = original_group->type; + array_init(group->conditions, SCENARIO_CONDITIONS_ARRAY_SIZE_STEP, original_group->conditions.constructor, + original_group->conditions.in_use); + for (unsigned int j = 0; j < original_group->conditions.size; j++) { + scenario_condition_t *condition; + array_new_item(group->conditions, condition); + *condition = *array_item(original_group->conditions, j); + + scenario_parameters_foreach_in_condition(condition, copy_formulas_condition); + } + } + data.event->id = event_id; + scenario_events_assign_parent_single_event_ids(data.event); + update_groups(); + window_request_refresh(); +} + static void set_repeat_type(void) { if (data.repeat_type == EVENT_REPEAT_NEVER) { @@ -1042,10 +1237,8 @@ static void handle_condition_tooltip(const grid_box_item *item, tooltip_context } static uint8_t text[MAX_TEXT_LENGTH * 2]; scenario_events_parameter_data_get_display_string_for_condition(list_item->condition, text, MAX_TEXT_LENGTH * 2); - if (text_get_width(text, FONT_NORMAL_BLACK) > item->width - 32) { - c->precomposed_text = text; - c->type = TOOLTIP_BUTTON; - } + c->precomposed_text = text; + c->type = TOOLTIP_BUTTON; } static void handle_action_tooltip(const grid_box_item *item, tooltip_context *c) @@ -1056,10 +1249,8 @@ static void handle_action_tooltip(const grid_box_item *item, tooltip_context *c) } static uint8_t text[MAX_TEXT_LENGTH * 2]; scenario_events_parameter_data_get_display_string_for_action(action, text, MAX_TEXT_LENGTH * 2); - if (text_get_width(text, FONT_NORMAL_BLACK) > item->width - 32) { - c->precomposed_text = text; - c->type = TOOLTIP_BUTTON; - } + c->precomposed_text = text; + c->type = TOOLTIP_BUTTON; } static void handle_check_all_none_tooltip(tooltip_context *c) diff --git a/src/window/file_dialog.c b/src/window/file_dialog.c index 1cb6910427..8ce690eb4e 100644 --- a/src/window/file_dialog.c +++ b/src/window/file_dialog.c @@ -632,7 +632,7 @@ static void confirm_save_file(int accepted, int checked) window_editor_custom_messages_show(); } else if (data.type == FILE_TYPE_MODEL_DATA) { scenario_model_export_to_xml(filename); - window_model_data_show(); + window_go_back(); } else if (data.type == FILE_TYPE_EMPIRE) { scenario_editor_set_custom_empire(data.selected_file); empire_export_xml(filename); @@ -738,7 +738,7 @@ static void button_ok_cancel(int is_ok, int param2) } else if (data.type == FILE_TYPE_MODEL_DATA) { int result = scenario_model_xml_parse_file(filename); if (result) { - window_model_data_show(); + window_go_back(); } else { window_plain_message_dialog_show(TR_EDITOR_UNABLE_TO_LOAD_MODEL_DATA_TITLE, TR_EDITOR_CHECK_LOG_MESSAGE, 1); return;