diff --git a/src/building/construction.c b/src/building/construction.c index bf68e5b26a..6ee88f9dc6 100644 --- a/src/building/construction.c +++ b/src/building/construction.c @@ -40,6 +40,7 @@ #include "map/tiles.h" #include "map/water.h" #include "map/water_supply.h" +#include "scenario/scenario_events_controller.h" #define MAX_CYCLE_SIZE 10 @@ -661,6 +662,8 @@ void building_construction_start(int x, int y, int grid_offset) } if (!can_start) { building_construction_cancel(); + } else { + scenario_events_full_process(EVENT_TRIGGER_BUILDING_PLACED_BY_PLAYER, 1, data.type); } } } diff --git a/src/building/construction_clear.c b/src/building/construction_clear.c index 269bfc5000..2d1ebe64be 100644 --- a/src/building/construction_clear.c +++ b/src/building/construction_clear.c @@ -17,6 +17,7 @@ #include "map/routing_terrain.h" #include "map/terrain.h" #include "map/tiles.h" +#include "scenario/scenario_events_controller.h" #include "translation/translation.h" #include "window/popup_dialog.h" @@ -30,6 +31,12 @@ static struct { int monument_confirmed; } confirm; +static void event_process_clearing(int building_type) +{ + scenario_events_full_process(EVENT_TRIGGER_BUILDING_CLEARED_BY_PLAYER, 1, BUILDING_AQUEDUCT); + scenario_events_full_process(EVENT_TRIGGER_BUILDING_DESTROYED_BY_ANYTHING, 1, BUILDING_AQUEDUCT); +} + static building *get_deletable_building(int grid_offset) { int building_id = map_building_at(grid_offset); @@ -144,10 +151,12 @@ static int clear_land_confirmed(int measure_only, int x_start, int y_start, int game_undo_add_building(space); space->state = BUILDING_STATE_DELETED_BY_PLAYER; } + event_process_clearing(b->type); } else if (map_terrain_is(grid_offset, TERRAIN_AQUEDUCT)) { map_terrain_remove(grid_offset, TERRAIN_CLEARABLE & ~TERRAIN_HIGHWAY); items_placed++; map_aqueduct_remove(grid_offset); + event_process_clearing(BUILDING_AQUEDUCT); } else if (map_terrain_is(grid_offset, TERRAIN_WATER)) { if (!measure_only && map_bridge_count_figures(grid_offset) > 0) { city_warning_show(WARNING_PEOPLE_ON_BRIDGE, NEW_WARNING_SLOT); @@ -159,8 +168,17 @@ static int clear_land_confirmed(int measure_only, int x_start, int y_start, int int next_highways_removed = map_tiles_clear_highway(grid_offset, measure_only); highways_removed += next_highways_removed; items_placed += next_highways_removed; + event_process_clearing(BUILDING_HIGHWAY); } else if (map_terrain_is(grid_offset, TERRAIN_NOT_CLEAR)) { - if (map_terrain_is(grid_offset, TERRAIN_ROAD | TERRAIN_GARDEN)) { + int is_road = map_terrain_is(grid_offset, TERRAIN_ROAD); + int is_garden = map_terrain_is(grid_offset, TERRAIN_GARDEN); + if (is_road) { + event_process_clearing(BUILDING_ROAD); + } + if (is_garden) { + event_process_clearing(BUILDING_GARDENS); + } + if (is_road || is_garden) { map_property_clear_plaza_earthquake_or_overgrown_garden(grid_offset); } map_terrain_remove(grid_offset, TERRAIN_CLEARABLE); diff --git a/src/building/destruction.c b/src/building/destruction.c index 0c77fa597d..f86b82c1f7 100644 --- a/src/building/destruction.c +++ b/src/building/destruction.c @@ -21,6 +21,12 @@ #include +static void event_process_destruction(event_trigger trigger, int building_type) +{ + scenario_events_full_process(trigger, 1, building_type); + scenario_events_full_process(EVENT_TRIGGER_BUILDING_DESTROYED_BY_ANYTHING, 1, building_type); +} + static void destroy_on_fire(building *b, int plagued) { game_undo_disable(); @@ -141,23 +147,31 @@ void building_destroy_by_collapse(building *b) destroy_linked_parts(b, 0, 0); } +void building_destroy_by_poor_maintenance(building *b) +{ + building_destroy_by_collapse(b); + event_process_destruction(EVENT_TRIGGER_BUILDING_DESTROYED_BY_POOR_MAINTENANCE, b->type); +} + void building_destroy_by_fire(building *b) { destroy_on_fire(b, 0); destroy_linked_parts(b, 1, 0); - scenario_events_progress_paused(EVENT_TRIGGER_BUILDING_DESTROYED_BY_FIRE, 1); + event_process_destruction(EVENT_TRIGGER_BUILDING_DESTROYED_BY_FIRE, b->type); } void building_destroy_by_plague(building *b) { destroy_on_fire(b, 1); destroy_linked_parts(b, 1, 1); + event_process_destruction(EVENT_TRIGGER_BUILDING_DESTROYED_BY_DISEASE, b->type); } void building_destroy_by_rioter(building *b) { destroy_on_fire(b, 0); destroy_linked_parts(b, 1, 0); + event_process_destruction(EVENT_TRIGGER_BUILDING_DESTROYED_BY_COMBAT, b->type); } int building_destroy_first_of_type(building_type type) @@ -212,16 +226,19 @@ void building_destroy_by_enemy(int x, int y, int grid_offset) if (b->state == BUILDING_STATE_IN_USE || b->state == BUILDING_STATE_MOTHBALLED) { city_ratings_peace_building_destroyed(b->type); building_destroy_by_collapse(b); + event_process_destruction(EVENT_TRIGGER_BUILDING_DESTROYED_BY_COMBAT, b->type); } } else { if (map_terrain_is(grid_offset, TERRAIN_WALL)) { figure_kill_tower_sentries_at(x, y); + event_process_destruction(EVENT_TRIGGER_BUILDING_DESTROYED_BY_COMBAT, BUILDING_WALL); } if (map_terrain_is(grid_offset, TERRAIN_GARDEN)) { map_terrain_remove(grid_offset, TERRAIN_CLEARABLE); map_tiles_update_region_empty_land(x, y, x, y); map_property_clear_plaza_earthquake_or_overgrown_garden(grid_offset); map_tiles_update_all_gardens(); + event_process_destruction(EVENT_TRIGGER_BUILDING_DESTROYED_BY_COMBAT, BUILDING_GARDENS); } else { map_building_tiles_set_rubble(0, x, y, 1); } diff --git a/src/building/destruction.h b/src/building/destruction.h index 4f43c017a0..2798af7214 100644 --- a/src/building/destruction.h +++ b/src/building/destruction.h @@ -5,6 +5,8 @@ void building_destroy_by_collapse(building *b); +void building_destroy_by_poor_maintenance(building *b); + void building_destroy_by_fire(building *b); void building_destroy_by_plague(building *b); diff --git a/src/building/maintenance.c b/src/building/maintenance.c index 3a0ef325b3..e7427ad7dc 100644 --- a/src/building/maintenance.c +++ b/src/building/maintenance.c @@ -153,7 +153,7 @@ static void collapse_building(building *b) } game_undo_disable(); - building_destroy_by_collapse(b); + building_destroy_by_poor_maintenance(b); } static void fire_building(building *b) diff --git a/src/game/tick.c b/src/game/tick.c index 1d2e4773db..f60e8b8f9a 100644 --- a/src/game/tick.c +++ b/src/game/tick.c @@ -13,6 +13,7 @@ #include "building/industry.h" #include "building/lighthouse.h" #include "building/maintenance.h" +#include "building/type.h" #include "building/warehouse.h" #include "city/buildings.h" #include "city/culture.h" @@ -115,8 +116,7 @@ static void advance_month(void) city_games_decrement_month_counts(); city_gods_update_blessings(); tutorial_on_month_tick(); - scenario_events_progress_paused(EVENT_TRIGGER_MONTH_START, 1); - scenario_events_process_by_trigger_type(EVENT_TRIGGER_MONTH_START); + scenario_events_full_process(EVENT_TRIGGER_MONTH_START, 1, BUILDING_NONE); if (setting_monthly_autosave()) { game_file_write_saved_game(dir_append_location("autosave.svx", PATH_LOCATION_SAVEGAME)); } diff --git a/src/scenario/condition_types/condition_handler.c b/src/scenario/condition_types/condition_handler.c index c0f1204b18..208c75ef4c 100644 --- a/src/scenario/condition_types/condition_handler.c +++ b/src/scenario/condition_types/condition_handler.c @@ -25,6 +25,8 @@ int scenario_condition_type_is_met(scenario_condition_t *condition) return scenario_condition_type_building_count_area_met(condition); case CONDITION_TYPE_CITY_POPULATION: return scenario_condition_type_city_population_met(condition); + case CONDITION_TYPE_CONTEXT_BUILDING_TYPE: + return scenario_condition_type_context_building_type_met(condition); case CONDITION_TYPE_COUNT_OWN_TROOPS: return scenario_condition_type_count_own_troops_met(condition); case CONDITION_TYPE_CUSTOM_VARIABLE_CHECK: diff --git a/src/scenario/condition_types/condition_types.c b/src/scenario/condition_types/condition_types.c index 79806ad117..442077920a 100644 --- a/src/scenario/condition_types/condition_types.c +++ b/src/scenario/condition_types/condition_types.c @@ -18,6 +18,7 @@ #include "map/grid.h" #include "scenario/request.h" #include "scenario/scenario.h" +#include "scenario/scenario_events_controller.h" #include "scenario/condition_types/comparison_helper.h" int scenario_condition_type_building_count_active_met(const scenario_condition_t *condition) @@ -210,6 +211,18 @@ int scenario_condition_type_city_population_met(const scenario_condition_t *cond return comparison_helper_compare_values(comparison, population_value_to_use, value); } +int scenario_condition_type_context_building_type_met(const scenario_condition_t *condition) +{ + int building_type = condition->parameter1; + + scenario_event_context_t *context = scenario_events_get_context(); + if (!context) { + return 0; + } + + return building_type == context->related_building_type; +} + int scenario_condition_type_count_own_troops_met(const scenario_condition_t *condition) { int comparison = condition->parameter1; diff --git a/src/scenario/condition_types/condition_types.h b/src/scenario/condition_types/condition_types.h index cf42711d75..4c02ec2814 100644 --- a/src/scenario/condition_types/condition_types.h +++ b/src/scenario/condition_types/condition_types.h @@ -13,6 +13,8 @@ int scenario_condition_type_city_population_met(const scenario_condition_t *cond int scenario_condition_type_count_own_troops_met(const scenario_condition_t *condition); +int scenario_condition_type_context_building_type_met(const scenario_condition_t *condition); + int scenario_condition_type_custom_variable_check_met(const scenario_condition_t *condition); int scenario_condition_type_difficulty_met(const scenario_condition_t *condition); diff --git a/src/scenario/scenario_event_data.h b/src/scenario/scenario_event_data.h index 75c0eafcc4..b212346417 100644 --- a/src/scenario/scenario_event_data.h +++ b/src/scenario/scenario_event_data.h @@ -21,6 +21,12 @@ typedef enum { EVENT_TRIGGER_UNDEFINED = 0, EVENT_TRIGGER_MONTH_START = 1, EVENT_TRIGGER_BUILDING_DESTROYED_BY_FIRE = 2, + EVENT_TRIGGER_BUILDING_DESTROYED_BY_POOR_MAINTENANCE = 3, + EVENT_TRIGGER_BUILDING_DESTROYED_BY_COMBAT = 4, + EVENT_TRIGGER_BUILDING_CLEARED_BY_PLAYER = 5, + EVENT_TRIGGER_BUILDING_DESTROYED_BY_DISEASE = 6, + EVENT_TRIGGER_BUILDING_DESTROYED_BY_ANYTHING = 7, + EVENT_TRIGGER_BUILDING_PLACED_BY_PLAYER = 8, EVENT_TRIGGER_MAX, } event_trigger; @@ -50,6 +56,7 @@ typedef enum { CONDITION_TYPE_RESOURCE_STORED_COUNT = 22, CONDITION_TYPE_RESOURCE_STORAGE_AVAILABLE = 23, CONDITION_TYPE_BUILDING_COUNT_AREA = 24, + CONDITION_TYPE_CONTEXT_BUILDING_TYPE = 25, CONDITION_TYPE_MAX, // helper constants CONDITION_TYPE_MIN = CONDITION_TYPE_TIME_PASSED, diff --git a/src/scenario/scenario_events_controller.c b/src/scenario/scenario_events_controller.c index 1cffd987a8..5379a22273 100644 --- a/src/scenario/scenario_events_controller.c +++ b/src/scenario/scenario_events_controller.c @@ -1,5 +1,6 @@ #include "scenario_events_controller.h" +#include "building/type.h" #include "core/log.h" #include "game/save_version.h" #include "scenario/action_types/action_handler.h" @@ -11,6 +12,8 @@ static array(scenario_event_t) scenario_events; +static scenario_event_context_t scenario_events_context; + static int event_in_use(const scenario_event_t *event) { return event->state != EVENT_STATE_UNDEFINED; @@ -27,6 +30,9 @@ void scenario_events_init(void) array_foreach(scenario_events, current) { scenario_event_init(current); } + + scenario_events_context.cause_of_context = EVENT_TRIGGER_UNDEFINED; + scenario_events_context.related_building_type = BUILDING_NONE; } void scenario_events_clear(void) @@ -73,6 +79,7 @@ scenario_event_t *scenario_event_create(int repeat_min, int repeat_max, int max_ event->repeat_triggers_min = repeat_min; event->repeat_triggers_max = repeat_max; event->max_number_of_repeats = max_repeats; + event->trigger = trigger_type; return event; } @@ -244,6 +251,16 @@ static void actions_load_state(buffer *buf) } } +static void scenario_events_progress_paused(event_trigger type_to_progress, int count) +{ + scenario_event_t *current; + array_foreach(scenario_events, current) { + if (current->trigger == type_to_progress) { + scenario_event_decrease_pause_count(current, count); + } + } +} + void scenario_events_load_state(buffer *buf_events, buffer *buf_conditions, buffer *buf_actions) { scenario_events_clear(); @@ -259,6 +276,12 @@ void scenario_events_load_state(buffer *buf_events, buffer *buf_conditions, buff } } +void scenario_events_set_context(event_trigger cause, building_type b_type) +{ + scenario_events_context.cause_of_context = cause; + scenario_events_context.related_building_type = b_type; +} + void scenario_events_process_by_trigger_type(event_trigger type_to_process) { scenario_event_t *current; @@ -269,6 +292,13 @@ void scenario_events_process_by_trigger_type(event_trigger type_to_process) } } +void scenario_events_full_process(event_trigger cause, int progress_count, building_type b_type) +{ + scenario_events_set_context(cause, b_type); + scenario_events_progress_paused(cause, progress_count); + scenario_events_process_by_trigger_type(cause); +} + scenario_event_t *scenario_events_get_using_custom_variable(int custom_variable_id) { scenario_event_t *current; @@ -280,12 +310,7 @@ scenario_event_t *scenario_events_get_using_custom_variable(int custom_variable_ return 0; } -void scenario_events_progress_paused(event_trigger type_to_progress, int count) +scenario_event_context_t *scenario_events_get_context(void) { - scenario_event_t *current; - array_foreach(scenario_events, current) { - if (current->trigger == type_to_progress) { - scenario_event_decrease_pause_count(current, count); - } - } + return &scenario_events_context; } diff --git a/src/scenario/scenario_events_controller.h b/src/scenario/scenario_events_controller.h index 8db08fa40d..c837849f6a 100644 --- a/src/scenario/scenario_events_controller.h +++ b/src/scenario/scenario_events_controller.h @@ -1,6 +1,7 @@ #ifndef SCENARIO_EVENTS_CONTOLLER_H #define SCENARIO_EVENTS_CONTOLLER_H +#include "building/building.h" #include "core/buffer.h" #include "scenario/scenario_event_data.h" @@ -12,6 +13,11 @@ typedef enum { SCENARIO_EVENTS_VERSION_TRIGGERS = 2, } scenario_events_version; +typedef struct { + event_trigger cause_of_context; + building_type related_building_type; +} scenario_event_context_t; + void scenario_events_init(void); void scenario_events_clear(void); scenario_event_t *scenario_event_get(int event_id); @@ -22,8 +28,11 @@ int scenario_events_get_count(void); void scenario_events_save_state(buffer *buf_events, buffer *buf_conditions, buffer *buf_actions); void scenario_events_load_state(buffer *buf_events, buffer *buf_conditions, buffer *buf_actions); +void scenario_events_set_context(event_trigger cause, building_type b_type); void scenario_events_process_by_trigger_type(event_trigger type_to_process); -void scenario_events_progress_paused(event_trigger type_to_progress, int count); +void scenario_events_full_process(event_trigger cause, int progress_count, building_type b_type); scenario_event_t *scenario_events_get_using_custom_variable(int custom_variable_id); +scenario_event_context_t *scenario_events_get_context(void); + #endif // SCENARIO_EVENTS_CONTOLLER_H diff --git a/src/scenario/scenario_events_parameter_data.c b/src/scenario/scenario_events_parameter_data.c index c823ca25e2..87a748d094 100644 --- a/src/scenario/scenario_events_parameter_data.c +++ b/src/scenario/scenario_events_parameter_data.c @@ -129,6 +129,9 @@ static scenario_condition_data_t scenario_condition_data[CONDITION_TYPE_MAX] = { .xml_parm3 = { .name = "building", .type = PARAMETER_TYPE_BUILDING, .key = TR_PARAMETER_TYPE_BUILDING_COUNTING }, .xml_parm4 = { .name = "check", .type = PARAMETER_TYPE_CHECK, .min_limit = 1, .max_limit = 6, .key = TR_PARAMETER_TYPE_CHECK }, .xml_parm5 = { .name = "value", .type = PARAMETER_TYPE_NUMBER, .min_limit = 0, .max_limit = UNLIMITED, .key = TR_PARAMETER_TYPE_NUMBER }, }, + [CONDITION_TYPE_CONTEXT_BUILDING_TYPE] = { .type = CONDITION_TYPE_CONTEXT_BUILDING_TYPE, + .xml_attr = { .name = "context_building_type", .type = PARAMETER_TYPE_TEXT, .key = TR_CONDITION_TYPE_CONTEXT_BUILDING_TYPE }, + .xml_parm1 = { .name = "building", .type = PARAMETER_TYPE_BUILDING, .key = TR_PARAMETER_TYPE_CONTEXT_BUILDING }, }, }; scenario_condition_data_t *scenario_events_parameter_data_get_conditions_xml_attributes(condition_types type) @@ -771,8 +774,14 @@ special_attribute_mapping_t special_attribute_mappings_climate[] = #define SPECIAL_ATTRIBUTE_MAPPINGS_CLIMATE_SIZE (sizeof(special_attribute_mappings_climate) / sizeof(special_attribute_mapping_t)) static special_attribute_mapping_t special_attribute_mappings_event_trigger_type[] = { - { .type = PARAMETER_TYPE_EVENT_TRIGGER_TYPE, .text = "start_of_month", .value = EVENT_TRIGGER_MONTH_START, .key = TR_PARAMETER_VALUE_EVENT_TRIGGER_MONTH_START }, - { .type = PARAMETER_TYPE_EVENT_TRIGGER_TYPE, .text = "on_building_destroyed", .value = EVENT_TRIGGER_BUILDING_DESTROYED_BY_FIRE, .key = TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED }, + { .type = PARAMETER_TYPE_EVENT_TRIGGER_TYPE, .text = "start_of_month", .value = EVENT_TRIGGER_MONTH_START, .key = TR_PARAMETER_VALUE_EVENT_TRIGGER_MONTH_START }, + { .type = PARAMETER_TYPE_EVENT_TRIGGER_TYPE, .text = "on_building_caught_fire", .value = EVENT_TRIGGER_BUILDING_DESTROYED_BY_FIRE, .key = TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_FIRE }, + { .type = PARAMETER_TYPE_EVENT_TRIGGER_TYPE, .text = "on_building_collapsed", .value = EVENT_TRIGGER_BUILDING_DESTROYED_BY_POOR_MAINTENANCE, .key = TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_POOR_MAINTENANCE }, + { .type = PARAMETER_TYPE_EVENT_TRIGGER_TYPE, .text = "on_building_raided", .value = EVENT_TRIGGER_BUILDING_DESTROYED_BY_COMBAT, .key = TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_COMBAT }, + { .type = PARAMETER_TYPE_EVENT_TRIGGER_TYPE, .text = "on_building_cleared", .value = EVENT_TRIGGER_BUILDING_CLEARED_BY_PLAYER, .key = TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_CLEARED_BY_PLAYER }, + { .type = PARAMETER_TYPE_EVENT_TRIGGER_TYPE, .text = "on_building_plagued", .value = EVENT_TRIGGER_BUILDING_DESTROYED_BY_DISEASE, .key = TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_DISEASE }, + { .type = PARAMETER_TYPE_EVENT_TRIGGER_TYPE, .text = "on_any_building_removal", .value = EVENT_TRIGGER_BUILDING_DESTROYED_BY_ANYTHING, .key = TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_ANYTHING }, + { .type = PARAMETER_TYPE_EVENT_TRIGGER_TYPE, .text = "on_building_placed", .value = EVENT_TRIGGER_BUILDING_PLACED_BY_PLAYER, .key = TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_PLACED_BY_PLAYER }, }; #define SPECIAL_ATTRIBUTE_MAPPINGS_EVENT_TRIGGER_TYPE_SIZE (sizeof(special_attribute_mappings_event_trigger_type) / sizeof(special_attribute_mapping_t)) @@ -1396,6 +1405,11 @@ void scenario_events_parameter_data_get_display_string_for_condition(scenario_co result_text = translation_for_number_value(condition->parameter5, result_text, &maxlength); return; } + case CONDITION_TYPE_CONTEXT_BUILDING_TYPE: + { + result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_BUILDING, condition->parameter1, result_text, &maxlength); + return; + } case CONDITION_TYPE_RESOURCE_STORAGE_AVAILABLE: { result_text = translation_for_type_lookup_by_value(PARAMETER_TYPE_STORAGE_TYPE, condition->parameter4, result_text, &maxlength); diff --git a/src/translation/english.c b/src/translation/english.c index 58636019f2..0263f5706f 100644 --- a/src/translation/english.c +++ b/src/translation/english.c @@ -1064,6 +1064,7 @@ static translation_string all_strings[] = { {TR_EDITOR_SCENARIO_EVENT_MAX_NUM_REPEATS, "Maximum number of repeats: "}, {TR_EDITOR_SCENARIO_EVENT_REPEATS_FOREVER, "Infinite"}, {TR_EDITOR_SCENARIO_EVENT_DOES_NOT_REPEAT, "Does not repeat."}, + {TR_EDITOR_SCENARIO_EVENT_TRIGGER, "Triggers when: "}, {TR_EDITOR_SCENARIO_EVENT_STATE_UNDEFINED, "Undefined"}, {TR_EDITOR_SCENARIO_EVENT_STATE_DISABLED, "Disabled"}, {TR_EDITOR_SCENARIO_EVENT_STATE_ACTIVE, "Active"}, @@ -1136,6 +1137,7 @@ static translation_string all_strings[] = { {TR_PARAMETER_TYPE_CLIMATE, "Climate" }, {TR_PARAMETER_TYPE_EVENT_TRIGGER_TYPE, "Event trigger type" }, {TR_PARAMETER_TYPE_BUILDING_DESTROYED_REASON, "Building destroyed reason" }, + {TR_PARAMETER_TYPE_CONTEXT_BUILDING, "Building type"}, {TR_CONDITION_TYPE_TIME_PASSED, "Time passed"}, {TR_CONDITION_TYPE_DIFFICULTY, "Difficulty"}, {TR_CONDITION_TYPE_MONEY, "City money"}, @@ -1160,6 +1162,7 @@ static translation_string all_strings[] = { {TR_CONDITION_TYPE_RESOURCE_STORED_COUNT, "Resource stored count"}, {TR_CONDITION_TYPE_RESOURCE_STORAGE_AVAILABLE, "Resource storage available"}, {TR_CONDITION_TYPE_BUILDING_COUNT_AREA, "Buildings in area"}, + {TR_CONDITION_TYPE_CONTEXT_BUILDING_TYPE, "Building type of building related event triggers"}, {TR_ACTION_TYPE_ADJUST_FAVOR, "Adjust favor"}, {TR_ACTION_TYPE_ADJUST_MONEY, "Adjust money"}, {TR_ACTION_TYPE_ADJUST_SAVINGS, "Adjust savings"}, @@ -1337,7 +1340,13 @@ static translation_string all_strings[] = { {TR_PARAMETER_VALUE_CLIMATE_NORTHERN, "Northern" }, {TR_PARAMETER_VALUE_CLIMATE_DESERT, "Desert" }, {TR_PARAMETER_VALUE_EVENT_TRIGGER_MONTH_START, "Start of month" }, - {TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED, "Building destroyed" }, + {TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_FIRE, "Building caught fire" }, + {TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_POOR_MAINTENANCE, "Building collapse from poor maintenance" }, + {TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_COMBAT, "Building destroyed by hostiles" }, + {TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_CLEARED_BY_PLAYER, "Building removed by player" }, + {TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_DISEASE, "Building burned due to plague" }, + {TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_ANYTHING, "Building removed for any reason" }, + {TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_PLACED_BY_PLAYER, "Building placed by player" }, {TR_PARAMETER_DISPLAY_SET_TO, "set to"}, {TR_PARAMETER_DISPLAY_ADD_TO, "add"}, {TR_PARAMETER_DISPLAY_BETWEEN, "between"}, diff --git a/src/translation/translation.h b/src/translation/translation.h index eac7a0a834..7a19134a94 100644 --- a/src/translation/translation.h +++ b/src/translation/translation.h @@ -1063,6 +1063,7 @@ typedef enum { TR_EDITOR_SCENARIO_EVENT_MAX_NUM_REPEATS, TR_EDITOR_SCENARIO_EVENT_REPEATS_FOREVER, TR_EDITOR_SCENARIO_EVENT_DOES_NOT_REPEAT, + TR_EDITOR_SCENARIO_EVENT_TRIGGER, TR_EDITOR_SCENARIO_EVENT_STATE_UNDEFINED, TR_EDITOR_SCENARIO_EVENT_STATE_DISABLED, TR_EDITOR_SCENARIO_EVENT_STATE_ACTIVE, @@ -1103,6 +1104,7 @@ typedef enum { TR_PARAMETER_TYPE_RESOURCE, TR_PARAMETER_TYPE_POP_CLASS, TR_PARAMETER_TYPE_BUILDING_COUNTING, + TR_PARAMETER_TYPE_CONTEXT_BUILDING, TR_PARAMETER_TYPE_ALLOWED_BUILDING, TR_PARAMETER_TYPE_ROUTE, TR_PARAMETER_TYPE_STANDARD_MESSAGE, @@ -1159,6 +1161,7 @@ typedef enum { TR_CONDITION_TYPE_RESOURCE_STORED_COUNT, TR_CONDITION_TYPE_RESOURCE_STORAGE_AVAILABLE, TR_CONDITION_TYPE_BUILDING_COUNT_AREA, + TR_CONDITION_TYPE_CONTEXT_BUILDING_TYPE, TR_ACTION_TYPE_ADJUST_FAVOR, TR_ACTION_TYPE_ADJUST_MONEY, TR_ACTION_TYPE_ADJUST_SAVINGS, @@ -1336,7 +1339,13 @@ typedef enum { TR_PARAMETER_VALUE_CLIMATE_NORTHERN, TR_PARAMETER_VALUE_CLIMATE_DESERT, TR_PARAMETER_VALUE_EVENT_TRIGGER_MONTH_START, - TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED, + TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_FIRE, + TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_POOR_MAINTENANCE, + TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_COMBAT, + TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_CLEARED_BY_PLAYER, + TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_DISEASE, + TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_DESTROYED_BY_ANYTHING, + TR_PARAMETER_VALUE_EVENT_TRIGGER_BUILDING_PLACED_BY_PLAYER, TR_PARAMETER_DISPLAY_SET_TO, TR_PARAMETER_DISPLAY_ADD_TO, TR_PARAMETER_DISPLAY_BETWEEN, diff --git a/src/window/editor/scenario_event_details.c b/src/window/editor/scenario_event_details.c index 32ff662539..ec16769897 100644 --- a/src/window/editor/scenario_event_details.c +++ b/src/window/editor/scenario_event_details.c @@ -18,6 +18,7 @@ #include "window/editor/map.h" #include "window/editor/scenario_action_edit.h" #include "window/editor/scenario_condition_edit.h" +#include "window/editor/select_special_attribute_mapping.h" #include "window/numeric_input.h" #define BUTTON_LEFT_PADDING 32 @@ -25,7 +26,7 @@ #define SHORT_BUTTON_LEFT_PADDING 128 #define SHORT_BUTTON_WIDTH 480 #define EVENT_REPEAT_Y_OFFSET 96 -#define DETAILS_Y_OFFSET 192 +#define DETAILS_Y_OFFSET 224 #define DETAILS_ROW_HEIGHT 32 #define MAX_VISIBLE_ROWS 10 #define MAX_TEXT_LENGTH 75 @@ -34,6 +35,7 @@ enum { SCENARIO_EVENT_DETAILS_SET_MAX_REPEATS = 0, SCENARIO_EVENT_DETAILS_SET_REPEAT_MIN, SCENARIO_EVENT_DETAILS_SET_REPEAT_MAX, + SCENARIO_EVENT_DETAILS_SET_TRIGGER, SCENARIO_EVENT_DETAILS_ADD_CONDITION, SCENARIO_EVENT_DETAILS_ADD_ACTION, }; @@ -43,6 +45,7 @@ static void init_scroll_list(void); static void on_scroll(void); static void button_click(int index, int param2); static void button_amount(int param1, int param2); +static void button_trigger_change(int param1, int param2); static void button_add(int param1, int param2); static void button_delete_event(int param1, int param2); static void add_new_condition(void); @@ -57,6 +60,7 @@ static generic_button buttons[] = { {SHORT_BUTTON_LEFT_PADDING, EVENT_REPEAT_Y_OFFSET, SHORT_BUTTON_WIDTH, 14, button_amount, button_none, SCENARIO_EVENT_DETAILS_SET_MAX_REPEATS, 0}, {SHORT_BUTTON_LEFT_PADDING, EVENT_REPEAT_Y_OFFSET + 32, SHORT_BUTTON_WIDTH, 14, button_amount, button_none, SCENARIO_EVENT_DETAILS_SET_REPEAT_MIN, 0}, {SHORT_BUTTON_LEFT_PADDING, EVENT_REPEAT_Y_OFFSET + 64, SHORT_BUTTON_WIDTH, 14, button_amount, button_none, SCENARIO_EVENT_DETAILS_SET_REPEAT_MAX, 0}, + {SHORT_BUTTON_LEFT_PADDING, EVENT_REPEAT_Y_OFFSET + 96, SHORT_BUTTON_WIDTH, 14, button_trigger_change, button_none, SCENARIO_EVENT_DETAILS_SET_TRIGGER, 0}, {BUTTON_LEFT_PADDING, DETAILS_Y_OFFSET + (0 * DETAILS_ROW_HEIGHT), BUTTON_WIDTH, DETAILS_ROW_HEIGHT - 2, button_click, button_none, 0, 0}, {BUTTON_LEFT_PADDING, DETAILS_Y_OFFSET + (1 * DETAILS_ROW_HEIGHT), BUTTON_WIDTH, DETAILS_ROW_HEIGHT - 2, button_click, button_none, 1, 0}, {BUTTON_LEFT_PADDING, DETAILS_Y_OFFSET + (2 * DETAILS_ROW_HEIGHT), BUTTON_WIDTH, DETAILS_ROW_HEIGHT - 2, button_click, button_none, 2, 0}, @@ -105,6 +109,7 @@ static struct { scenario_event_t *event; sub_item_entry_t list[MAX_VISIBLE_ROWS]; + uint8_t display_text[MAX_TEXT_LENGTH]; } data; static void populate_list(int offset) @@ -195,6 +200,13 @@ static void init_scroll_list(void) populate_list(0); } +static uint8_t *translation_for_param_value(parameter_type type, int value) +{ + memset(data.display_text, 0, MAX_TEXT_LENGTH); + scenario_events_parameter_data_get_display_string_for_value(type, value, data.display_text, MAX_TEXT_LENGTH); + return data.display_text; +} + static int color_from_state(event_state state) { if (!editor_is_active()) { @@ -270,8 +282,18 @@ static void draw_foreground(void) data.event->repeat_triggers_max, "", SHORT_BUTTON_LEFT_PADDING + 16, y_offset + 8, FONT_NORMAL_GREEN, COLOR_MASK_NONE); + int button_id = 4; + large_label_draw(buttons[button_id].x, buttons[button_id].y, buttons[button_id].width / 16, + data.focus_button_id == button_id + 1 ? 1 : 0); + text_draw_centered(translation_for(TR_EDITOR_SCENARIO_EVENT_TRIGGER), + buttons[button_id].x, buttons[button_id].y + 8, buttons[button_id].width / 2, + FONT_NORMAL_GREEN, COLOR_MASK_NONE); + text_draw_centered(translation_for_param_value(PARAMETER_TYPE_EVENT_TRIGGER_TYPE, data.event->trigger), + buttons[button_id].x + BUTTON_WIDTH / 2, buttons[button_id].y + 8, buttons[button_id].width / 2, + FONT_NORMAL_GREEN, COLOR_MASK_NONE); + y_offset = DETAILS_Y_OFFSET; - int i_button_offset = 4; + int i_button_offset = 5; for (unsigned int i = 0; i < MAX_VISIBLE_ROWS; i++) { if (data.list[i].sub_type != SUB_ITEM_TYPE_UNDEFINED) { large_label_draw(buttons[i + i_button_offset].x, buttons[i + i_button_offset].y, @@ -386,6 +408,16 @@ static void button_click(int index, int param2) } } +static void set_event_trigger_value(int value) +{ + data.event->trigger = value; +} + +static void button_trigger_change(int param1, int param2) +{ + window_editor_select_special_attribute_mapping_show(PARAMETER_TYPE_EVENT_TRIGGER_TYPE, set_event_trigger_value, data.event->trigger); +} + static void button_amount(int param1, int param2) { if (param1 == SCENARIO_EVENT_DETAILS_SET_MAX_REPEATS) {