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;