From 28c4c4ac8d6c506c54513fb8e8cbf34cb8cd6017 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 11 Feb 2023 02:33:39 +0200 Subject: [PATCH 22/22] sdl2: Make Alliance clause available in diplomacy dialog See osdn #46604 Signed-off-by: Marko Lindqvist --- client/gui-sdl2/diplodlg.c | 4 ++-- common/player.c | 43 ++++++++++++++++++++------------------ common/player.h | 2 +- server/sanitycheck.c | 1 + server/savegame2.c | 3 ++- server/savegame3.c | 3 ++- 6 files changed, 31 insertions(+), 25 deletions(-) diff --git a/client/gui-sdl2/diplodlg.c b/client/gui-sdl2/diplodlg.c index 10c1cda1ff..910bed5fcb 100644 --- a/client/gui-sdl2/diplodlg.c +++ b/client/gui-sdl2/diplodlg.c @@ -535,7 +535,7 @@ static struct ADVANCED_DLG *popup_diplomatic_objects(struct player *pPlayer0, count++; } - if (pplayer_can_make_treaty(pPlayer0, pPlayer1, DS_ALLIANCE)) { + if (pplayer_can_make_treaty(pPlayer0, pPlayer1, DS_ALLIANCE) == DIPL_OK) { fc_snprintf(cBuf, sizeof(cBuf), " %s", Q_("?diplomatic_state:Alliance")); pBuf = create_iconlabel_from_chars(NULL, pWindow->dst, @@ -1552,7 +1552,7 @@ void popup_diplomacy_dialog(struct player *pPlayer) fc_snprintf(cBuf, sizeof(cBuf), _("Cancel Treaty")); } - /* cancel treaty */ + /* Cancel treaty */ pBuf = create_themeicon_button_from_chars(current_theme->UNITS2_Icon, pWindow->dst, cBuf, adj_font(12), 0); diff --git a/common/player.c b/common/player.c index 5244a72c94..c7af1fed53 100644 --- a/common/player.c +++ b/common/player.c @@ -84,10 +84,10 @@ enum diplstate_type cancel_pact_result(enum diplstate_type oldstate) } /*************************************************************** - The senate may not allow you to break the treaty. In this - case you must first dissolve the senate then you can break - it. This is waived if you have statue of liberty since you - could easily just dissolve and then recreate it. + The senate may not allow you to break the treaty. In this + case you must first dissolve the senate then you can break + it. This is waived if you have statue of liberty since you + could easily just dissolve and then recreate it. ***************************************************************/ enum dipl_reason pplayer_can_cancel_treaty(const struct player *p1, const struct player *p2) @@ -108,21 +108,22 @@ enum dipl_reason pplayer_can_cancel_treaty(const struct player *p1, && get_player_bonus(p1, EFT_NO_ANARCHY) <= 0) { return DIPL_SENATE_BLOCKING; } + return DIPL_OK; } /*************************************************************** - Returns true iff p1 can be in alliance with p2. + Returns TRUE iff p1 can be in alliance with p2. - Check that we are not at war with any of p2's allies. Note - that for an alliance to be made, we need to check this both + Check that we are not at war with any of p2's allies. Note + that for an alliance to be made, we need to check this both ways. - The reason for this is to avoid the dread 'love-love-hate' + The reason for this is to avoid the dread 'love-love-hate' triad, in which p1 is allied to p2 is allied to p3 is at war with p1. These lead to strange situations. ***************************************************************/ -static bool is_valid_alliance(const struct player *p1, +static bool is_valid_alliance(const struct player *p1, const struct player *p2) { players_iterate_alive(pplayer) { @@ -130,7 +131,7 @@ static bool is_valid_alliance(const struct player *p1, if (pplayer != p1 && pplayer != p2 - && ds == DS_WAR /* do not count 'never met' as war here */ + && ds == DS_WAR /* Do not count 'never met' as war here */ && pplayers_allied(p2, pplayer)) { return FALSE; } @@ -140,12 +141,13 @@ static bool is_valid_alliance(const struct player *p1, } /*************************************************************** - Returns true iff p1 can make given treaty with p2. + Returns the reason p1 can't make given treaty with p2, + or DIPL_OK if they can. We cannot regress in a treaty chain. So we cannot suggest 'Peace' if we are in 'Alliance'. Then you have to cancel. - For alliance there is only one condition: We are not at war + For alliance there is only one condition: We are not at war with any of p2's allies. ***************************************************************/ enum dipl_reason pplayer_can_make_treaty(const struct player *p1, @@ -162,17 +164,17 @@ enum dipl_reason pplayer_can_make_treaty(const struct player *p1, || get_player_bonus(p2, EFT_NO_DIPLOMACY) > 0) { return DIPL_ERROR; } - if (treaty == DS_WAR - || treaty == DS_NO_CONTACT - || treaty == DS_ARMISTICE + if (treaty == DS_WAR + || treaty == DS_NO_CONTACT + || treaty == DS_ARMISTICE || treaty == DS_TEAM || treaty == DS_LAST) { - return DIPL_ERROR; /* these are not negotiable treaties */ + return DIPL_ERROR; /* These are not negotiable treaties */ } if (treaty == DS_CEASEFIRE && existing != DS_WAR) { - return DIPL_ERROR; /* only available from war */ + return DIPL_ERROR; /* Only available from war */ } - if (treaty == DS_PEACE + if (treaty == DS_PEACE && (existing != DS_WAR && existing != DS_CEASEFIRE)) { return DIPL_ERROR; } @@ -185,15 +187,16 @@ enum dipl_reason pplayer_can_make_treaty(const struct player *p1, return DIPL_ALLIANCE_PROBLEM_THEM; } } - /* this check must be last: */ + /* This check must be last: */ if (treaty == existing) { return DIPL_ERROR; } + return DIPL_OK; } /*************************************************************** - Check if pplayer has an embassy with pplayer2. We always have + Check if pplayer has an embassy with pplayer2. We always have an embassy with ourselves. ***************************************************************/ bool player_has_embassy(const struct player *pplayer, diff --git a/common/player.h b/common/player.h index 6f2dab580d..00815e5944 100644 --- a/common/player.h +++ b/common/player.h @@ -195,7 +195,7 @@ enum dipl_reason { DIPL_ALLIANCE_PROBLEM_US, DIPL_ALLIANCE_PROBLEM_THEM }; -/* the following are for "pacts" */ +/* The following are for "pacts" */ struct player_diplstate { enum diplstate_type type; /* this player's disposition towards other */ enum diplstate_type max_state; /* maximum treaty level ever had */ diff --git a/server/sanitycheck.c b/server/sanitycheck.c index 810f2e059e..85e931bb78 100644 --- a/server/sanitycheck.c +++ b/server/sanitycheck.c @@ -557,6 +557,7 @@ static void check_players(const char *file, const char *function, int line) && pplayers_allied(pplayer, pplayer2)) { enum dipl_reason allied_players_can_be_allied = pplayer_can_make_treaty(pplayer, pplayer2, DS_ALLIANCE); + SANITY_CHECK(allied_players_can_be_allied != DIPL_ALLIANCE_PROBLEM_US); SANITY_CHECK(allied_players_can_be_allied diff --git a/server/savegame2.c b/server/savegame2.c index e236829a25..d19925e77a 100644 --- a/server/savegame2.c +++ b/server/savegame2.c @@ -2705,6 +2705,7 @@ static void sg_load_players(struct loaddata *loading) if (pplayers_allied(plr, aplayer)) { enum dipl_reason can_ally = pplayer_can_make_treaty(plr, aplayer, DS_ALLIANCE); + if (can_ally == DIPL_ALLIANCE_PROBLEM_US || can_ally == DIPL_ALLIANCE_PROBLEM_THEM) { log_sg("Illegal alliance structure detected: " @@ -2728,7 +2729,7 @@ static void sg_load_players(struct loaddata *loading) } cities_iterate_end; } - /* Update all city information. This must come after all cities are + /* Update all city information. This must come after all cities are * loaded (in player_load) but before player (dumb) cities are loaded * in player_load_vision(). */ players_iterate(plr) { diff --git a/server/savegame3.c b/server/savegame3.c index 09291c0cb9..13f9e56c10 100644 --- a/server/savegame3.c +++ b/server/savegame3.c @@ -3588,6 +3588,7 @@ static void sg_load_players(struct loaddata *loading) if (pplayers_allied(plr, aplayer)) { enum dipl_reason can_ally = pplayer_can_make_treaty(plr, aplayer, DS_ALLIANCE); + if (can_ally == DIPL_ALLIANCE_PROBLEM_US || can_ally == DIPL_ALLIANCE_PROBLEM_THEM) { log_sg("Illegal alliance structure detected: " @@ -3611,7 +3612,7 @@ static void sg_load_players(struct loaddata *loading) } cities_iterate_end; } - /* Update all city information. This must come after all cities are + /* Update all city information. This must come after all cities are * loaded (in player_load) but before player (dumb) cities are loaded * in player_load_vision(). */ players_iterate(plr) { -- 2.39.1