Skip to content

Commit

Permalink
Merge pull request #830 from cazfi/srvup
Browse files Browse the repository at this point in the history
  • Loading branch information
cazfi authored Apr 12, 2024
2 parents df59735 + 9810e59 commit d6d511b
Show file tree
Hide file tree
Showing 4 changed files with 319 additions and 2 deletions.
8 changes: 8 additions & 0 deletions freeciv/apply_patches.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
# 0051-Adjust-nationality-of-remaining-units-after-player-r.patch
# Fix to player removal
# RM #383
# 0038-AI-Delay-war-declaration-until-really-revolted.patch
# AI senate dismissal fix
# osdn #48018
# 0053-AI-Fix-bad-city-spot-value-calculation-with-unknown-.patch
# AI city spot evaluation fix
# RM #408

# Not in the upstream Freeciv server
# ----------------------------------
Expand Down Expand Up @@ -49,6 +55,8 @@ declare -a PATCHLIST=(
"backports/0002-Fix-allied-victory-of-all-players"
"backports/0041-Stop-sending-hidden-resources-to-the-client"
"backports/0051-Adjust-nationality-of-remaining-units-after-player-r"
"backports/0038-AI-Delay-war-declaration-until-really-revolted"
"backports/0053-AI-Fix-bad-city-spot-value-calculation-with-unknown-"
"RevertAmplio2ExtraUnits"
"meson_webperimental"
"metachange"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
From e6a03444059c7b1b0e2ab87c2bdf8c31379c9e73 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <[email protected]>
Date: Mon, 1 Apr 2024 04:05:55 +0300
Subject: [PATCH 38/51] AI: Delay war declaration until really revolted

If senate is blocking war declaration, don't try to
declare war as soon as have only decided to overthrow the senate.
Instead store the war target and wait until senate is
really overthrown before declaring the war

See osdn #48018

Signed-off-by: Marko Lindqvist <[email protected]>
---
ai/classic/classicai.c | 12 +++++++
ai/default/daidata.h | 7 ++--
ai/default/daidiplomacy.c | 69 +++++++++++++++++++++++++++++----------
ai/default/daidiplomacy.h | 3 ++
ai/tex/texai.c | 11 +++++++
common/ai.h | 3 ++
server/plrhand.c | 2 ++
7 files changed, 87 insertions(+), 20 deletions(-)

diff --git a/ai/classic/classicai.c b/ai/classic/classicai.c
index 7e11ee6206..6e47c6dded 100644
--- a/ai/classic/classicai.c
+++ b/ai/classic/classicai.c
@@ -579,6 +579,16 @@ static void cai_consider_wonder_city(struct city *pcity, bool *result)
dai_consider_wonder_city(deftype, pcity, result);
}

+/**********************************************************************//**
+ Call default ai with classic ai type as parameter.
+**************************************************************************/
+static void cai_revolution_start(struct player *pplayer)
+{
+ struct ai_type *deftype = classic_ai_get_self();
+
+ dai_revolution_start(deftype, pplayer);
+}
+
/**********************************************************************//**
Setup player ai_funcs function pointers.
**************************************************************************/
@@ -691,5 +701,7 @@ bool fc_ai_classic_setup(struct ai_type *ai)
/* ai->funcs.city_info = NULL; */
/* ai->funcs.unit_info = NULL; */

+ ai->funcs.revolution_start = cai_revolution_start;
+
return TRUE;
}
diff --git a/ai/default/daidata.h b/ai/default/daidata.h
index 756d526984..80b169bf9c 100644
--- a/ai/default/daidata.h
+++ b/ai/default/daidata.h
@@ -75,11 +75,11 @@ struct ai_plr
int last_num_oceans;

struct {
- int passengers; /* number of passengers waiting for boats */
+ int passengers; /* Number of passengers waiting for boats */
int boats;
int available_boats;

- int *workers; /* cities to workers on continent */
+ int *workers; /* Cities to workers on continent */
int *ocean_workers;

bv_id diplomat_reservations;
@@ -89,11 +89,12 @@ struct ai_plr
struct {
const struct ai_dip_intel **player_intel_slots;
enum winning_strategy strategy;
- int timer; /* pursue our goals with some stubbornness, in turns */
+ int timer; /* Pursue our goals with some stubbornness, in turns */
char love_coeff; /* Reduce love with this % each turn */
char love_incr; /* Modify love with this fixed amount */
int req_love_for_peace;
int req_love_for_alliance;
+ struct player *war_target;
} diplomacy;

/* Cache map for AI settlers; defined in daisettler.c. */
diff --git a/ai/default/daidiplomacy.c b/ai/default/daidiplomacy.c
index f28b6c9f23..6ac46a7fb8 100644
--- a/ai/default/daidiplomacy.c
+++ b/ai/default/daidiplomacy.c
@@ -1299,6 +1299,41 @@ static void dai_share(struct ai_type *ait, struct player *pplayer,
}
}

+/******************************************************************//**
+ AI to declare war.
+
+ @param ait AI type of the player declaring war
+ @param pplayer Player declaring war
+ @param target Player to declare war to
+**********************************************************************/
+static void dai_declare_war(struct ai_type *ait, struct player *pplayer,
+ struct player *target)
+{
+ struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, target);
+
+ /* This will take us straight to war. */
+ while (player_diplstate_get(pplayer, target)->type != DS_WAR) {
+ if (pplayer_can_cancel_treaty(pplayer, target) != DIPL_OK) {
+ DIPLO_LOG(ait, LOG_ERROR, pplayer, target,
+ "Wanted to cancel treaty but was unable to.");
+ adip->countdown = -1; /* War declaration aborted */
+
+ return;
+ }
+ handle_diplomacy_cancel_pact(pplayer, player_number(target), clause_type_invalid());
+ }
+
+ /* Throw a tantrum */
+ if (pplayer->ai_common.love[player_index(target)] > 0) {
+ pplayer->ai_common.love[player_index(target)] = -1;
+ }
+ pplayer->ai_common.love[player_index(target)] -= MAX_AI_LOVE / 8;
+
+ fc_assert(!gives_shared_vision(pplayer, target));
+
+ DIPLO_LOG(ait, LOG_DIPL, pplayer, target, "war declared");
+}
+
/******************************************************************//**
Go to war. Explain to target why we did it, and set countdown to
some negative value to make us a bit stubborn to avoid immediate
@@ -1380,6 +1415,8 @@ static void dai_go_to_war(struct ai_type *ait, struct player *pplayer,
pplayer->government = real_gov;
handle_player_change_government(pplayer,
game.info.government_during_revolution_id);
+ def_ai_player_data(pplayer, ait)->diplomacy.war_target = target;
+ return;
} else {
/* There would be Senate even during revolution. Better not to revolt for nothing */
pplayer->government = real_gov;
@@ -1392,26 +1429,24 @@ static void dai_go_to_war(struct ai_type *ait, struct player *pplayer,
}
}

- /* This will take us straight to war. */
- while (player_diplstate_get(pplayer, target)->type != DS_WAR) {
- if (pplayer_can_cancel_treaty(pplayer, target) != DIPL_OK) {
- DIPLO_LOG(ait, LOG_ERROR, pplayer, target,
- "Wanted to cancel treaty but was unable to.");
- adip->countdown = -1; /* War declaration aborted */
+ dai_declare_war(ait, pplayer, target);
+}

- return;
- }
- handle_diplomacy_cancel_pact(pplayer, player_number(target), clause_type_invalid());
- }
+/******************************************************************//**
+ Revolution start callback for default AI.

- /* Throw a tantrum */
- if (pplayer->ai_common.love[player_index(target)] > 0) {
- pplayer->ai_common.love[player_index(target)] = -1;
- }
- pplayer->ai_common.love[player_index(target)] -= MAX_AI_LOVE / 8;
+ @param ait AI type of the player revolting
+ @param pplayer Player revolting
+**********************************************************************/
+void dai_revolution_start(struct ai_type *ait, struct player *pplayer)
+{
+ struct ai_plr *data = def_ai_player_data(pplayer, ait);

- fc_assert(!gives_shared_vision(pplayer, target));
- DIPLO_LOG(ait, LOG_DIPL, pplayer, target, "war declared");
+ if (data->diplomacy.war_target != NULL) {
+ dai_declare_war(ait, pplayer, data->diplomacy.war_target);
+
+ data->diplomacy.war_target = NULL;
+ }
}

/******************************************************************//**
diff --git a/ai/default/daidiplomacy.h b/ai/default/daidiplomacy.h
index 77b5c76f45..74e4a10e39 100644
--- a/ai/default/daidiplomacy.h
+++ b/ai/default/daidiplomacy.h
@@ -13,6 +13,7 @@
#ifndef FC__DAIDIPLOMACY_H
#define FC__DAIDIPLOMACY_H

+/* common */
#include "fc_types.h"

#include "ai.h" /* incident_type */
@@ -40,4 +41,6 @@ bool dai_on_war_footing(struct ai_type *ait, struct player *pplayer);
void dai_diplomacy_first_contact(struct ai_type *ait, struct player *pplayer,
struct player *aplayer);

+void dai_revolution_start(struct ai_type *ait, struct player *pplayer);
+
#endif /* FC__DAIDIPLOMACY_H */
diff --git a/ai/tex/texai.c b/ai/tex/texai.c
index e7f39c1ab2..e7aded9e8e 100644
--- a/ai/tex/texai.c
+++ b/ai/tex/texai.c
@@ -566,6 +566,15 @@ static void texwai_refresh(struct player *pplayer)
TEXAI_TFUNC(texai_refresh, pplayer);
}

+/**********************************************************************//**
+ Call default ai with tex ai type as parameter.
+**************************************************************************/
+static void texwai_revolution_start(struct player *pplayer)
+{
+ TEXAI_AIT;
+ TEXAI_TFUNC(dai_revolution_start, pplayer);
+}
+
/**********************************************************************//**
Return module capability string
**************************************************************************/
@@ -676,5 +685,7 @@ bool fc_ai_tex_setup(struct ai_type *ai)
ai->funcs.city_info = texai_city_changed;
ai->funcs.unit_info = texai_unit_changed;

+ ai->funcs.revolution_start = texwai_revolution_start;
+
return TRUE;
}
diff --git a/common/ai.h b/common/ai.h
index 5162d611e8..22c568dda3 100644
--- a/common/ai.h
+++ b/common/ai.h
@@ -316,6 +316,9 @@ struct ai_type
*/
void (*unit_info)(struct unit *punit);

+ /* Called for player AI when revolution starts. */
+ void (*revolution_start)(struct player *pplayer);
+
/* These are here reserving space for future optional callbacks.
* This way we don't need to change the mandatory capability of the AI module
* interface when adding such callbacks, but existing modules just have these
diff --git a/server/plrhand.c b/server/plrhand.c
index 8b796b3f43..2ce80c4366 100644
--- a/server/plrhand.c
+++ b/server/plrhand.c
@@ -621,6 +621,8 @@ void handle_player_change_government(struct player *pplayer,
government_rule_name(pplayer->target_government),
pplayer->revolution_finishes, game.info.turn);

+ CALL_PLR_AI_FUNC(revolution_start, pplayer, pplayer);
+
/* Now see if the revolution is instantaneous. */
if (turns <= 0
&& pplayer->target_government != game.government_during_revolution) {
--
2.43.0

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
From 940ce754eba1d509a24b11427f715e8ef2306075 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <[email protected]>
Date: Sun, 7 Apr 2024 00:35:33 +0300
Subject: [PATCH 53/53] AI: Fix bad city spot value calculation with unknown
tiles

Unknown and already worked tiles counted as negative output value.
Now they count as 0, as they cannot produce anything for the city.

See RM #408

Signed-off-by: Marko Lindqvist <[email protected]>
---
ai/default/daisettler.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/ai/default/daisettler.c b/ai/default/daisettler.c
index 7372167d81..3395dfa9e8 100644
--- a/ai/default/daisettler.c
+++ b/ai/default/daisettler.c
@@ -374,17 +374,22 @@ static struct cityresult *cityresult_fill(struct ai_type *ait,
result->best_other.tile = ptile;
result->best_other.cindex = cindex;
} else if (ptdc->sum > result->best_other.tdc->sum) {
- /* First add other other to remaining */
- result->remaining += result->best_other.tdc->sum
- / GROWTH_POTENTIAL_DEEMPHASIS;
+ /* First add other other to remaining, unless it's unavailable (value < 0) tile. */
+ if (result->best_other.tdc->sum > 0) {
+ result->remaining += result->best_other.tdc->sum
+ / GROWTH_POTENTIAL_DEEMPHASIS;
+ }
/* Then make new best other */
result->best_other.tdc = ptdc;
result->best_other.tile = ptile;
result->best_other.cindex = cindex;
} else {
/* Save total remaining calculation, divided by crowdedness
- * of the area and the emphasis placed on space for growth. */
- result->remaining += ptdc->sum / GROWTH_POTENTIAL_DEEMPHASIS;
+ * of the area and the emphasis placed on space for growth.
+ * Do not add unavailable (value < 0) tiles. */
+ if (ptdc->sum > 0) {
+ result->remaining += ptdc->sum / GROWTH_POTENTIAL_DEEMPHASIS;
+ }
}

tile_data_cache_hash_replace(result->tdc_hash, cindex, ptdc);
--
2.43.0

4 changes: 2 additions & 2 deletions freeciv/version.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# The Git SHA hash for the commit to checkout from
# https://github.com/freeciv/freeciv

FCREV=d19ae091673f8d49f9ca48c39c7c3c017ad19887
FCREV=5d3d7f1af11bb6703784b957447017507df82774

ORIGCAPSTR="+Freeciv.Devel-\${MAIN_VERSION}-2024.Feb.28"
ORIGCAPSTR="+Freeciv.Devel-\${MAIN_VERSION}-2024.Mar.08"

# There's no need to bump this constantly as current freeciv-web
# makes no connections to outside world - all connections are
Expand Down

0 comments on commit d6d511b

Please sign in to comment.