diff --git a/src/building/building.c b/src/building/building.c index 98ea5c1e99..406e31f6fd 100644 --- a/src/building/building.c +++ b/src/building/building.c @@ -205,6 +205,7 @@ building *building_create(building_type type, int x, int y) // subtype if (building_is_house(type)) { + b->cooldown_advanced_sentiment = type < BUILDING_HOUSE_SMALL_VILLA ? ADVANCED_SENTIMENT_COOLDOWN_TICKS : 0; b->subtype.house_level = type - BUILDING_HOUSE_VACANT_LOT; } @@ -268,7 +269,7 @@ static void building_delete(building *b) void building_clear_related_data(building *b) { - if (b->storage_id) { + if (building_uses_storage(b->type) && b->storage_id) { building_storage_delete(b->storage_id); b->storage_id = 0; } @@ -424,6 +425,11 @@ int building_is_house(building_type type) return type >= BUILDING_HOUSE_VACANT_LOT && type <= BUILDING_HOUSE_LUXURY_PALACE; } +int building_uses_storage(building_type type) +{ + return type == BUILDING_WAREHOUSE || type == BUILDING_GRANARY; +} + // For Venus GT base bonus int building_is_statue_garden_temple(building_type type) { diff --git a/src/building/building.h b/src/building/building.h index c40afb358b..83dbf379a7 100644 --- a/src/building/building.h +++ b/src/building/building.h @@ -7,6 +7,10 @@ #include "game/resource.h" #include "translation/translation.h" +// Ticks of cooldown before new advanced sentiment logic will be applied +// for the house building. Each tick is equal to 8 days (half of month). +#define ADVANCED_SENTIMENT_COOLDOWN_TICKS 36 + typedef enum order_condition_type { ORDER_CONDITION_NEVER = 0, ORDER_CONDITION_ALWAYS, @@ -180,6 +184,7 @@ typedef struct building { signed char house_happiness; signed char native_anger; } sentiment; + uint8_t cooldown_advanced_sentiment; unsigned char show_on_problem_overlay; unsigned char house_tavern_wine_access; unsigned char house_tavern_food_access; @@ -232,6 +237,11 @@ void building_update_state(void); void building_update_desirability(void); +/** + * Checks if building can store goods + */ +int building_uses_storage(building_type type); + int building_is_house(building_type type); int building_is_ceres_temple(building_type type); diff --git a/src/building/state.c b/src/building/state.c index 326df7f687..00ffd45d2b 100644 --- a/src/building/state.c +++ b/src/building/state.c @@ -1,5 +1,7 @@ #include "state.h" +#include + #include "building/industry.h" #include "building/monument.h" #include "building/roadblock.h" @@ -164,6 +166,13 @@ void building_state_save_to_buffer(buffer *buf, const building *b) buffer_write_u8(buf, b->is_adjacent_to_water); buffer_write_u8(buf, b->storage_id); buffer_write_i8(buf, b->sentiment.house_happiness); // which union field we use does not matter + + if (building_is_house(b->type)) { + buffer_write_u8(buf, b->cooldown_advanced_sentiment); + } else { + buffer_skip(buf, sizeof(b->cooldown_advanced_sentiment)); + } + buffer_write_u8(buf, b->show_on_problem_overlay); // expanded building data @@ -486,8 +495,20 @@ void building_state_load_from_buffer(buffer *buf, building *b, int building_buf_ b->desirability = buffer_read_i8(buf); b->is_deleted = buffer_read_u8(buf); b->is_adjacent_to_water = buffer_read_u8(buf); - b->storage_id = buffer_read_u8(buf); + if (building_uses_storage(b->type)) { + b->storage_id = buffer_read_u8(buf); + } else { + b->storage_id = 0; + buffer_skip(buf, 1); + } b->sentiment.house_happiness = buffer_read_i8(buf); // which union field we use does not matter + if (save_version >= SAVE_GAME_LAST_ADVANCED_SENTIMENT) { + if (building_is_house(b->type)) { + b->cooldown_advanced_sentiment = buffer_read_u8(buf); + } else { + buffer_skip(buf, sizeof(b->cooldown_advanced_sentiment)); + } + } b->show_on_problem_overlay = buffer_read_u8(buf); // Wharves produce fish and don't need any progress diff --git a/src/building/state.h b/src/building/state.h index b7f466a6a1..f8b7ac5934 100644 --- a/src/building/state.h +++ b/src/building/state.h @@ -11,10 +11,11 @@ #define BUILDING_STATE_TOURISM_BUFFER_SIZE (BUILDING_STATE_ORIGINAL_BUFFER_SIZE + 6) // 134 #define BUILDING_STATE_VARIANTS_AND_UPGRADES (BUILDING_STATE_TOURISM_BUFFER_SIZE + 2) // 136 #define BUILDING_STATE_STRIKES (BUILDING_STATE_VARIANTS_AND_UPGRADES + 1) // 137 -#define BUILDING_STATE_SICKNESS (BUILDING_STATE_STRIKES + 5) // 142 +#define BUILDING_STATE_SICKNESS (BUILDING_STATE_ADV_SENTIMENT + 5) // 142 #define BUILDING_STATE_WITHOUT_RESOURCES (BUILDING_STATE_SICKNESS - RESOURCE_MAX_LEGACY) // 126 (plus variable resource size) #define BUILDING_STATE_DYNAMIC_RESOURCES (BUILDING_STATE_WITHOUT_RESOURCES + BUILDING_STATE_NONSTATIC_RESOURCE_SIZE) #define BUILDING_STATE_CURRENT_BUFFER_SIZE (BUILDING_STATE_DYNAMIC_RESOURCES + 8) +#define BUILDING_STATE_ADV_SENTIMENT (BUILDING_STATE_STRIKES + sizeof(uint8_t)) void building_state_save_to_buffer(buffer *buf, const building *b); diff --git a/src/city/gods.c b/src/city/gods.c index c36c955d39..c689ef40c7 100644 --- a/src/city/gods.c +++ b/src/city/gods.c @@ -115,7 +115,7 @@ static void perform_small_curse(god_type god) city_message_post(1, MESSAGE_VENUS_IS_UPSET, 0, 0); city_data.sentiment.blessing_festival_boost -= 15; city_health_change(-10); - city_sentiment_update(); + city_sentiment_update(0); break; } } @@ -162,7 +162,7 @@ static int perform_large_curse(god_type god) city_health_change(-20); } city_data.religion.venus_curse_active = 1; - city_sentiment_update(); + city_sentiment_update(0); break; } return 1; diff --git a/src/city/sentiment.c b/src/city/sentiment.c index 16645c86ef..446546ae10 100644 --- a/src/city/sentiment.c +++ b/src/city/sentiment.c @@ -13,6 +13,8 @@ #include "core/config.h" #include "core/random.h" #include "game/difficulty.h" +#include "game/settings.h" +#include "game/time.h" #include "game/tutorial.h" #include @@ -35,6 +37,22 @@ #define IMPERIAL_GAMES_SENTIMENT_BONUS 15 #define POP_STEP_FOR_BASE_AVERAGE_HOUSE_LEVEL 625 +#define min(a,b) \ +({ \ + __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a < _b ? _a : _b; \ +}) + +// New advanced sentiment change calculation applies only after city reaches +// population of 1000. This is required to prevent very fast sentiment drop +// by high unemployment at very early game +#define ADVANCED_SENTIMENT_CHANGE_APPLY_AFTER_POPULATION 1000 + +// The effect from wages setting is divided by 8dn intervals. Each next interval +// reduces or increases modifier for every denarii set above or below Rome pays. +#define WAGE_SENTIMENT_CHANGE_INTERVAL 8 + int city_sentiment(void) { return city_data.sentiment.value; @@ -168,8 +186,54 @@ static int get_games_bonus(void) static int get_wage_sentiment_modifier(void) { + if (city_data.labor.wages == city_data.labor.wages_rome) { + return 0; + } + const int wage_interval = WAGE_SENTIMENT_CHANGE_INTERVAL; + int use_advanced_sentiment_contribution = config_get(CONFIG_GP_CH_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION); int wage_differential = city_data.labor.wages - city_data.labor.wages_rome; - return wage_differential * (wage_differential > 0 ? WAGE_POSITIVE_MODIFIER : WAGE_NEGATIVE_MODIFIER); + if (use_advanced_sentiment_contribution && wage_differential > wage_interval) { + // Extra sentiment bonus modifier applies when player sets higher wages than Rome. Wage range is + // divided by 8dn intervals. For every next wage interval the modifier is decreased by 1/2. + // Example: + // Rome pays 30dn, player sets current wage level to 55dn. Wage difference will be 25dn and + // the interval length is 8dn. Base bonus modifier is 2. Modifier will be set for every + // wage interval to values [2, 1, 0.5, 0.25]. + // The final modifier: 8 * 2 + 8 * 1 + 8 * 0.5 + 1 * 0.25) = 28 (original value was 50). + int remaining = abs(wage_differential); + wage_differential = 0; + + int modifier = 100 * WAGE_POSITIVE_MODIFIER; + while (remaining > 0) { + int diff = calc_bound(remaining, 1, wage_interval); + wage_differential += diff * modifier; + remaining -= diff; + modifier /= 2; + } + wage_differential /= 100; + } else if (use_advanced_sentiment_contribution && wage_differential < -wage_interval) { + // Extra sentiment punishment modifier applies when player sets lower wages than Rome. Wage range is + // divided by 8dn intervals. For every next wage interval the modifier is increased by 1/2. + // Example: + // Rome pays 40dn, player sets current wage level to 15dn. Wage difference will be -25dn and + // the interval length is 8dn. Base punishment modifier is 3. Modifier will be set for every + // wage interval to values [3, 4.5, 6.75, 10.125]. + // The final modifier: -(8 * 3 + 8 * 4.5 + 8 * 6.75 + 1 * 10.125) = -124 (original value was -75). + int remaining = abs(wage_differential); + wage_differential = 0; + + int modifier = 100 * WAGE_NEGATIVE_MODIFIER; + while (remaining > 0) { + int diff = calc_bound(remaining, 1, wage_interval); + wage_differential -= diff * modifier; + remaining -= diff; + modifier += modifier / 2; // adds 50% sentiment points reduction + } + wage_differential /= 100; + } else { + wage_differential *= (wage_differential > 0 ? WAGE_POSITIVE_MODIFIER : WAGE_NEGATIVE_MODIFIER); + } + return wage_differential; } static int get_unemployment_sentiment_modifier(void) @@ -184,9 +248,34 @@ static int get_unemployment_sentiment_modifier(void) static int get_sentiment_modifier_for_tax_rate(int tax) { int base_tax = difficulty_base_tax_rate(); - int tax_differential = base_tax - tax; - tax_differential *= tax_differential < 0 ? (MAX_TAX_MULTIPLIER - base_tax) : (base_tax / 2); - return tax_differential; + int interval = calc_bound(base_tax / 2, 1, 8); // Calculate the tax interval length based on difficulty + int sentiment_modifier = base_tax - tax; // The original base sentiment modifier if advanced logic isn't enabled + if (sentiment_modifier < -interval && config_get(CONFIG_GP_CH_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION)) { + // Extra sentiment punishment modifier applies when player sets higher taxes. Tax range is + // divided by intervals which length is half of base tax rate based on difficulty settings. + // For every next tax interval the modifier is increased by 1/3. + // Example: + // In very hard mode the base tax rate is 6%. Player sets current tax level to 16%. + // Tax difference will be 10% and the interval length is 3% (half of base tax rate 6%). + // Base punishment modifier is a diff between 12% and base tax rate (6%). + // Modifier will be set for every tax interval to values [6, 8, 10.66, 14.2]. + // The final modifier: -(3% * 6 + 3% * 8 + 3% * 10.66 + 1% * 14.2) = -88 (original value was -60). + int remaining = abs(sentiment_modifier); + sentiment_modifier = 0; + + int modifier = 100 * (MAX_TAX_MULTIPLIER - base_tax); + while (remaining > 0) { + int diff = calc_bound(remaining, 1, interval); + sentiment_modifier -= diff * modifier; + remaining -= diff; + modifier += modifier / 3; // adds 33% sentiment points reduction + } + sentiment_modifier /= 100; + } else { + sentiment_modifier *= sentiment_modifier < 0 ? (MAX_TAX_MULTIPLIER - base_tax) : (base_tax / 2); + } + + return sentiment_modifier; } static int get_average_housing_level(void) @@ -250,7 +339,50 @@ static int extra_food_bonus(int types, int required) return calc_bound(extra, 0, MAX_SENTIMENT_FROM_EXTRA_FOOD); } -void city_sentiment_update(void) +const int advanced_sentiment_gain_modifier[5] = { + 30, // Very Easy + 25, // Easy + 20, // Normal + 17, // Hard + 15 // Very Hard +}; + +const int advanced_sentiment_drop_modifier[5] = { + 30, // Very Easy + 35, // Easy + 40, // Normal + 45, // Hard + 50 // Very Hard +}; + +// Updates house building sentiment cooldown by delta value. +// Returns 1 if advanced sentiment logic should be applied to house and 0 if not +int update_house_advanced_sentiment_cooldown(building *b, int sentiment_cooldown_delta) { + if (!building_is_house(b->type)) { + return 0; + } + + if (b->type >= BUILDING_HOUSE_SMALL_VILLA) { + // Reset cooldown for villas + b->cooldown_advanced_sentiment = 0; + } else if (b->type == BUILDING_HOUSE_VACANT_LOT) { + // Wait for new citizens to arrive + return 0; + } + + if (sentiment_cooldown_delta > 0 && b->cooldown_advanced_sentiment > 0) { + b->cooldown_advanced_sentiment -= min(sentiment_cooldown_delta, b->cooldown_advanced_sentiment); + } + + if (!b->cooldown_advanced_sentiment) { + // Cooldown has ended + return 1; + } + + return 0; +} + +void city_sentiment_update(int sentiment_cooldown_delta) { city_population_check_consistency(); @@ -269,6 +401,8 @@ void city_sentiment_update(void) int total_pop = 0; int total_houses = 0; int house_level_sentiment_multiplier = 3; + int apply_advanced_sentiment_change = config_get(CONFIG_GP_CH_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION) && + city_data.population.population >= ADVANCED_SENTIMENT_CHANGE_APPLY_AFTER_POPULATION; for (building_type type = BUILDING_HOUSE_SMALL_TENT; type <= BUILDING_HOUSE_LUXURY_PALACE; type++) { if (type == BUILDING_HOUSE_SMALL_SHACK) { @@ -288,11 +422,11 @@ void city_sentiment_update(void) } int sentiment = default_sentiment; - - if (b->house_tax_coverage) { - sentiment += sentiment_contribution_taxes; + if (b->subtype.house_level > HOUSE_GRAND_INSULA) { + // Reduce sentiment contribution from taxes for villas by 20% + sentiment += (b->house_tax_coverage ? sentiment_contribution_taxes : sentiment_contribution_no_tax) * 8 / 10; } else { - sentiment += sentiment_contribution_no_tax; + sentiment += b->house_tax_coverage ? sentiment_contribution_taxes : sentiment_contribution_no_tax; } if (b->subtype.house_level <= HOUSE_GRAND_INSULA) { @@ -321,9 +455,32 @@ void city_sentiment_update(void) sentiment += blessing_festival_boost; + sentiment = calc_bound(sentiment, 0, 100); // new sentiment value should be in range of 0..100 + // Change sentiment gradually to the new value int sentiment_delta = sentiment - b->sentiment.house_happiness; - sentiment_delta = calc_bound(sentiment_delta, -MAX_SENTIMENT_CHANGE, MAX_SENTIMENT_CHANGE); + if (sentiment_delta != 0 && + update_house_advanced_sentiment_cooldown(b, sentiment_cooldown_delta) && + apply_advanced_sentiment_change + ) { + // With new advanced logic we introduce faster sentiment change when the target value is + // far away from current happiness level. The final change value depends on difficulty settings. + // Example #1: + // Current house happiness level is 82, the new sentiment value is 10 and the delta is -72. + // The final happiness change for VeryHard mode will be -36 (50% of -72). + // Example #2: + // Current house happiness level is 20, the new sentiment value is 77 and the delta is 57. + // The final happiness change for Hard mode will be 9 (17% of 57). + if (sentiment_delta > 0) { + int gain_modifier = advanced_sentiment_gain_modifier[setting_difficulty()]; + sentiment_delta = calc_bound(sentiment_delta * gain_modifier / 100, 1, 100); + } else { + int drop_modifier = advanced_sentiment_drop_modifier[setting_difficulty()]; + sentiment_delta = calc_bound(sentiment_delta * drop_modifier / 100, -100, -1); + } + } else { + sentiment_delta = calc_bound(sentiment_delta, -MAX_SENTIMENT_CHANGE, MAX_SENTIMENT_CHANGE); + } b->sentiment.house_happiness = calc_bound(b->sentiment.house_happiness + sentiment_delta, 0, 100); houses_calculated++; diff --git a/src/city/sentiment.h b/src/city/sentiment.h index bb87fa2ad3..a159280f58 100644 --- a/src/city/sentiment.h +++ b/src/city/sentiment.h @@ -25,6 +25,6 @@ void city_sentiment_reduce_crime_cooldown(void); int city_sentiment_get_blessing_festival_boost(void); void city_sentiment_decrement_blessing_boost(void); -void city_sentiment_update(void); +void city_sentiment_update(int sentiment_cooldown_delta); #endif // CITY_SENTIMENT_H diff --git a/src/core/config.c b/src/core/config.c index 303f0947d5..1b02fe3c1c 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -72,6 +72,7 @@ static const char *ini_keys[] = { "gameplay_change_yearly_autosave", "gameplay_change_auto_kill_animals", "gameplay_change_nonmilitary_gates_allow_walkers", + "gameplay_change_advanced_tax_wage_sentiment_contribution", "ui_show_speedrun_info", "ui_show_desirability_range", }; diff --git a/src/core/config.h b/src/core/config.h index 184f78c0d2..950a5abca4 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -62,6 +62,7 @@ typedef enum { CONFIG_GP_CH_YEARLY_AUTOSAVE, CONFIG_GP_CH_AUTO_KILL_ANIMALS, CONFIG_GP_CH_GATES_DEFAULT_TO_PASS_ALL_WALKERS, + CONFIG_GP_CH_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION, CONFIG_UI_SHOW_SPEEDRUN_INFO, CONFIG_UI_SHOW_DESIRABILITY_RANGE, CONFIG_MAX_ENTRIES diff --git a/src/figuretype/trader.c b/src/figuretype/trader.c index d37d4bddc7..566b1743d4 100644 --- a/src/figuretype/trader.c +++ b/src/figuretype/trader.c @@ -128,7 +128,7 @@ int figure_trade_caravan_can_buy(figure *trader, int building_id, int city_id) int figure_trade_caravan_can_sell(figure *trader, int building_id, int city_id) { building *b = building_get(building_id); - if (b->type != BUILDING_WAREHOUSE && b->type != BUILDING_GRANARY) { + if (!building_uses_storage(b->type)) { return 0; } if (b->has_plague) { diff --git a/src/game/save_version.h b/src/game/save_version.h index 63b0b0a82f..aba89315d4 100644 --- a/src/game/save_version.h +++ b/src/game/save_version.h @@ -41,7 +41,8 @@ typedef enum { SAVE_GAME_LAST_WRONG_SCENARIO_END_OFFSET = 0x9b, SAVE_GAME_LAST_NO_CUSTOM_EMPIRE_MAP_IMAGE = 0x9c, SAVE_GAME_LAST_NO_CUSTOM_CAMPAIGNS = 0x9d, - SAVE_GAME_LAST_STATIC_SCENARIO_ORIGINAL_DATA = 0x9e + SAVE_GAME_LAST_STATIC_SCENARIO_ORIGINAL_DATA = 0x9e, + SAVE_GAME_LAST_ADVANCED_SENTIMENT = 0x9f } savegame_version_t; typedef enum { diff --git a/src/game/tick.c b/src/game/tick.c index c484e8afde..48e5ea3b1d 100644 --- a/src/game/tick.c +++ b/src/game/tick.c @@ -131,7 +131,7 @@ static void advance_day(void) advance_month(); } if (game_time_day() == 0 || game_time_day() == 8) { - city_sentiment_update(); + city_sentiment_update(1); } if (game_time_day() == 0 || game_time_day() == 7) { building_lighthouse_consume_timber(); diff --git a/src/translation/english.c b/src/translation/english.c index 086404b976..1edcb0befe 100644 --- a/src/translation/english.c +++ b/src/translation/english.c @@ -112,6 +112,7 @@ static translation_string all_strings[] = { {TR_CONFIG_DRAW_CLOUD_SHADOWS, "Draw cloud shadows"}, {TR_CONFIG_ASK_CONFIRMATION_ON_FILE_OVERWRITE, "Ask for confirmation when overwriting a file"}, {TR_CONFIG_GATES_DEFAULT_TO_PASS_ALL_WALKERS, "Non-military gates default to allowing all walkers"}, + {TR_CONFIG_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION, "Advanced tax and wage sentiment contribution logic"}, {TR_HOTKEY_TITLE, "Augustus hotkey configuration"}, {TR_HOTKEY_LABEL, "Hotkey"}, {TR_HOTKEY_ALTERNATIVE_LABEL, "Alternative"}, diff --git a/src/translation/french.c b/src/translation/french.c index d41167779f..ef1b00da78 100644 --- a/src/translation/french.c +++ b/src/translation/french.c @@ -112,6 +112,7 @@ static translation_string all_strings[] = { {TR_CONFIG_DRAW_CLOUD_SHADOWS, "Simuler l'ombre des nuages"}, {TR_CONFIG_ASK_CONFIRMATION_ON_FILE_OVERWRITE, "Demander confirmation pour écraser un fichier"}, {TR_CONFIG_GATES_DEFAULT_TO_PASS_ALL_WALKERS, "Les arches non-militaires autorisent par défaut tous les marcheurs"}, + {TR_CONFIG_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION, "Logique avancée de contribution au sentiment fiscal et salarial"}, {TR_HOTKEY_TITLE, "Configuration raccourcis clavier"}, {TR_HOTKEY_LABEL, "Touche"}, {TR_HOTKEY_ALTERNATIVE_LABEL, "Alternative"}, diff --git a/src/translation/german.c b/src/translation/german.c index baf306273f..55defdc008 100644 --- a/src/translation/german.c +++ b/src/translation/german.c @@ -119,6 +119,7 @@ static translation_string all_strings[] = { {TR_CONFIG_FULLSCREEN, "Vollbild"}, {TR_CONFIG_GAME_SPEED, "Spielgeschwindigkeit:"}, {TR_CONFIG_GATES_DEFAULT_TO_PASS_ALL_WALKERS, "Nicht-militärische Tore lassen standardmäßig alle Fußgänger zu"}, + {TR_CONFIG_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION, "Erweiterte Steuer- und Lohnstimmungsbeitragslogik"}, {TR_CONFIG_GETTING_GRANARIES_GO_OFFROAD, "Karrenschieber fordernder Silos laufen auch abseits der Straße"}, {TR_CONFIG_GLOBAL_LABOUR, "Aktiviere globalen Arbeiterpool"}, {TR_CONFIG_GODS_EFFECTS, "Götterflüche/-segnungen aktivieren"}, diff --git a/src/translation/greek.c b/src/translation/greek.c index 4d1720c2c1..21a44ff23c 100644 --- a/src/translation/greek.c +++ b/src/translation/greek.c @@ -113,6 +113,7 @@ static translation_string all_strings[] = { {TR_CONFIG_ASK_CONFIRMATION_ON_FILE_OVERWRITE, "Ζητήστε επιβεβαίωση όταν αντικαθιστάτε ένα αρχείο"}, {TR_HOTKEY_TITLE, "Ρύθμιση πλήκτρων συντομεύσεων του Augustus"}, {TR_CONFIG_GATES_DEFAULT_TO_PASS_ALL_WALKERS, "Οι μη στρατιωτικές πύλες επιτρέπουν από προεπιλογή όλους τους περιπατητές"}, + {TR_CONFIG_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION, "Προηγμένη λογική εισφοράς φόρου και μισθολογικού κλίματος"}, {TR_HOTKEY_LABEL, "Πλήκτρα συντόμευσης"}, {TR_HOTKEY_ALTERNATIVE_LABEL, "Εναλλακτικά"}, {TR_HOTKEY_HEADER_ARROWS, "Πλήκτρα βέλους"}, diff --git a/src/translation/italian.c b/src/translation/italian.c index b6c5d80d84..9ce2537eee 100644 --- a/src/translation/italian.c +++ b/src/translation/italian.c @@ -112,6 +112,7 @@ static translation_string all_strings[] = { {TR_CONFIG_DRAW_CLOUD_SHADOWS, "Disegna le ombre delle nuvole"}, {TR_CONFIG_ASK_CONFIRMATION_ON_FILE_OVERWRITE, "Chiedi conferma alla sovrascrittura di un file"}, {TR_CONFIG_GATES_DEFAULT_TO_PASS_ALL_WALKERS, "I portali civili fanno passare tutti i passeggiatori di default"}, + {TR_CONFIG_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION, "Logica avanzata di contributo al sentimento fiscale e salariale"}, {TR_HOTKEY_TITLE, "Configura scorciatoie da tastiera Augustus"}, {TR_HOTKEY_LABEL, "Tasto"}, {TR_HOTKEY_ALTERNATIVE_LABEL, "Alternativa"}, diff --git a/src/translation/korean.c b/src/translation/korean.c index 87bac8d3b0..017691547f 100644 --- a/src/translation/korean.c +++ b/src/translation/korean.c @@ -112,6 +112,7 @@ static translation_string all_strings[] = { {TR_CONFIG_DRAW_CLOUD_SHADOWS, "구름 그림자 표시"}, {TR_CONFIG_ASK_CONFIRMATION_ON_FILE_OVERWRITE, "파일을 덮어쓰기 전에 물어보기"}, {TR_CONFIG_GATES_DEFAULT_TO_PASS_ALL_WALKERS, "비군사형 문이 모든 시민이 통과 가능하도록 초기 설정됨"}, + {TR_CONFIG_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION, "고급 세금 및 임금 감정 기여 논리"}, {TR_HOTKEY_TITLE, "Augustus 단축키 설정"}, {TR_HOTKEY_LABEL, "단축키"}, {TR_HOTKEY_ALTERNATIVE_LABEL, "대체"}, diff --git a/src/translation/polish.c b/src/translation/polish.c index 7cbec2a40b..9c01a524df 100644 --- a/src/translation/polish.c +++ b/src/translation/polish.c @@ -1017,6 +1017,7 @@ static translation_string all_strings[] = { {TR_CONFIG_AUTO_KILL_ANIMALS, "Obywatele będą automatycznie zabijać nieszkodliwe zwierzęta"}, {TR_CONFIG_DRAW_CLOUD_SHADOWS, "Narysuj cienie chmur"}, {TR_CONFIG_GATES_DEFAULT_TO_PASS_ALL_WALKERS, "Bramy niemilitarne domyślnie przepuszczają wszystkich obywateli"}, + {TR_CONFIG_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION, "Zaawansowana logika wliczania podatków i nastrojów płacowych"}, {TR_CONFIG_SHOW_MARKET_RANGE, "Pokaż zasięg przy budowie nowych targów"}, {TR_CONFIG_SHOW_ROAMING_PATH, "Podgląd ścieżek przebytych przez wędrujących obywateli"}, {TR_CONFIG_SHOW_WATER_STRUCTURE_RANGE_HOUSES, "Pokaż zasięg fontann i studni podczas budowy domów"}, diff --git a/src/translation/portuguese.c b/src/translation/portuguese.c index 7805c74d91..0e93d68da8 100644 --- a/src/translation/portuguese.c +++ b/src/translation/portuguese.c @@ -1063,6 +1063,7 @@ static translation_string all_strings[] = { {TR_CONFIG_ASK_CONFIRMATION_ON_FILE_OVERWRITE, "Solicitar confirmação para substituir arquivo"}, {TR_CONFIG_DRAW_CLOUD_SHADOWS, "Desenhar sombras de nuvens"}, {TR_CONFIG_GATES_DEFAULT_TO_PASS_ALL_WALKERS, "Sincronizar portões não militares para permitir todo tipo de trabalhador"}, + {TR_CONFIG_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION, "Lógica avançada de contribuição de sentimento fiscal e salarial"}, {TR_EDITOR_CHECK_LOG_MESSAGE, "Por favor, confira augustus-log.txt no seu diretório do Augustus para detalhes."}, {TR_EDITOR_CUSTOM_MESSAGES_CLEAR, "Apagar mensagens" }, {TR_EDITOR_CUSTOM_MESSAGES_COUNT, "Total de mensagens" }, diff --git a/src/translation/russian.c b/src/translation/russian.c index 4ce33ce64e..747157c20b 100644 --- a/src/translation/russian.c +++ b/src/translation/russian.c @@ -112,6 +112,7 @@ static translation_string all_strings[] = { {TR_CONFIG_DRAW_CLOUD_SHADOWS, "Показать тени облаков"}, {TR_CONFIG_ASK_CONFIRMATION_ON_FILE_OVERWRITE, "Запрашивать подтверждение при перезаписи файла"}, {TR_CONFIG_GATES_DEFAULT_TO_PASS_ALL_WALKERS, "Невоенные ворота по умолчанию пропускают всех пешеходов"}, + {TR_CONFIG_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION, "Расширенная логика подсчета влияния налогов & жалований на настроение жителей"}, {TR_HOTKEY_TITLE, "Настройки горячих клавиш Augustus"}, {TR_HOTKEY_LABEL, "Основная"}, {TR_HOTKEY_ALTERNATIVE_LABEL, "Альтернативная"}, diff --git a/src/translation/spanish.c b/src/translation/spanish.c index 4d43881fc1..4ab88d87b3 100644 --- a/src/translation/spanish.c +++ b/src/translation/spanish.c @@ -112,6 +112,7 @@ static translation_string all_strings[] = { {TR_CONFIG_DRAW_CLOUD_SHADOWS, "Dibuja sombras de nubes"}, {TR_CONFIG_ASK_CONFIRMATION_ON_FILE_OVERWRITE, "Preguntar el confirmar al sobreescribir un archivo"}, {TR_CONFIG_GATES_DEFAULT_TO_PASS_ALL_WALKERS, "Puertas no militar permite por defecto a los caminantes "}, + {TR_CONFIG_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION, "Lógica avanzada de contribución al sentimiento salarial e impositivo"}, {TR_HOTKEY_TITLE, "Configuración de atajos de teclado de Augustus"}, {TR_HOTKEY_LABEL, "Principal"}, {TR_HOTKEY_ALTERNATIVE_LABEL, "Alternativo"}, diff --git a/src/translation/swedish.c b/src/translation/swedish.c index 3b21f3729a..2f3d3d798c 100644 --- a/src/translation/swedish.c +++ b/src/translation/swedish.c @@ -1004,6 +1004,7 @@ static translation_string all_strings[] = { {TR_CONFIG_ASK_CONFIRMATION_ON_FILE_OVERWRITE, "Be om bekräftelse när en fil skrivs över"}, {TR_CONFIG_DRAW_CLOUD_SHADOWS, "Visa skuggor från moln"}, {TR_CONFIG_GATES_DEFAULT_TO_PASS_ALL_WALKERS, "Icke-militära grindar förinställda att att tillåta strövande medborgare"}, + {TR_CONFIG_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION, "Avancerad skatte- och lönesentimentbidragslogik"}, {TR_FIGURE_INFO_DEPOT_DELIVER, "Levererar"}, {TR_FIGURE_INFO_DEPOT_FROM, "Från "}, {TR_FIGURE_INFO_DEPOT_RECALL, "Återkalla"}, diff --git a/src/translation/translation.h b/src/translation/translation.h index 95231d6727..3e9785aed6 100644 --- a/src/translation/translation.h +++ b/src/translation/translation.h @@ -106,6 +106,7 @@ typedef enum { TR_CONFIG_DRAW_CLOUD_SHADOWS, TR_CONFIG_ASK_CONFIRMATION_ON_FILE_OVERWRITE, TR_CONFIG_GATES_DEFAULT_TO_PASS_ALL_WALKERS, + TR_CONFIG_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION, TR_HOTKEY_TITLE, TR_HOTKEY_LABEL, TR_HOTKEY_ALTERNATIVE_LABEL, diff --git a/src/widget/city_overlay_other.c b/src/widget/city_overlay_other.c index 3d93457a44..c1ab9c206f 100644 --- a/src/widget/city_overlay_other.c +++ b/src/widget/city_overlay_other.c @@ -116,7 +116,7 @@ static int show_building_logistics(const building *b) static int show_building_storages(const building *b) { b = building_main((building *) b); - return b->storage_id > 0 && building_storage_get(b->storage_id); + return building_uses_storage(b->type) && b->storage_id > 0 && building_storage_get(b->storage_id); } static int show_building_none(const building *b) @@ -915,8 +915,8 @@ static void draw_storage_ids(int x, int y, float scale, int grid_offset) } int building_id = map_building_at(grid_offset); building *b = building_get(building_id); - if (!b || b->is_deleted || map_property_is_deleted(b->grid_offset) || !b->storage_id || - !map_property_is_draw_tile(grid_offset)) { + if (!b || !building_uses_storage(b->type) || b->is_deleted || map_property_is_deleted(b->grid_offset) || + !b->storage_id || !map_property_is_draw_tile(grid_offset)) { return; } uint8_t number[10]; diff --git a/src/window/config.c b/src/window/config.c index 7701888fba..2b71e370fb 100644 --- a/src/window/config.c +++ b/src/window/config.c @@ -238,6 +238,7 @@ static config_widget all_widgets[CONFIG_PAGES][MAX_WIDGETS] = { {TYPE_CHECKBOX, CONFIG_GP_CH_WOLVES_BLOCK, TR_CONFIG_WOLVES_BLOCK }, {TYPE_CHECKBOX, CONFIG_GP_CH_MULTIPLE_BARRACKS, TR_CONFIG_MULTIPLE_BARRACKS }, {TYPE_CHECKBOX, CONFIG_GP_CH_DISABLE_INFINITE_WOLVES_SPAWNING, TR_CONFIG_GP_CH_DISABLE_INFINITE_WOLVES_SPAWNING }, + {TYPE_CHECKBOX, CONFIG_GP_CH_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION, TR_CONFIG_ADVANCED_TAX_WAGE_SENTIMENT_CONTRIBUTION}, {TYPE_NUMERICAL_DESC, RANGE_MAX_GRAND_TEMPLES, TR_CONFIG_MAX_GRAND_TEMPLES}, {TYPE_NUMERICAL_RANGE, RANGE_MAX_GRAND_TEMPLES, 0, display_text_max_grand_temples}, },