From 0371ca3dad418bfe5ccbeb637c72c303e94bba16 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 9 Oct 2021 18:47:34 +0300 Subject: [PATCH 13/48] Add only_real_fight_makes_veteran ruleset setting Requested by bard See osdn #43009 Signed-off-by: Marko Lindqvist --- common/game.h | 1 - common/networking/packets.def | 1 + data/alien/game.ruleset | 6 ++++++ data/civ1/game.ruleset | 6 ++++++ data/civ2/game.ruleset | 6 ++++++ data/civ2civ3/game.ruleset | 6 ++++++ data/classic/game.ruleset | 6 ++++++ data/goldkeep/game.ruleset | 6 ++++++ data/granularity/game.ruleset | 6 ++++++ data/multiplayer/game.ruleset | 6 ++++++ data/ruledit/comments-3.2.txt | 7 +++++++ data/sandbox/game.ruleset | 6 ++++++ data/stub/game.ruleset | 6 ++++++ data/webperimental/game.ruleset | 6 ++++++ fc_version | 2 +- server/ruleset.c | 4 ++++ server/ruleset.h | 3 +++ server/unithand.c | 5 +++-- server/unittools.c | 28 ++++++++++++++++++---------- server/unittools.h | 5 +++-- tools/ruleutil/comments.c | 13 +++++++++++++ tools/ruleutil/comments.h | 1 + tools/ruleutil/rulesave.c | 6 ++++++ 23 files changed, 126 insertions(+), 16 deletions(-) diff --git a/common/game.h b/common/game.h index b20e0cc54d..09199e3217 100644 --- a/common/game.h +++ b/common/game.h @@ -828,7 +828,6 @@ extern struct world wld; #define RS_DEFAULT_CIVIL_WAR_UNHAPPY 5 #define RS_DEFAULT_TIRED_ATTACK FALSE -#define RS_DEFAULT_ONLY_KILLING_VETERAN FALSE #define RS_DEFAULT_NUKE_POP_LOSS_PCT 49 #define RS_MIN_NUKE_POP_LOSS_PCT 0 #define RS_MAX_NUKE_POP_LOSS_PCT 100 diff --git a/common/networking/packets.def b/common/networking/packets.def index 5c243c3c7d..60380e1297 100644 --- a/common/networking/packets.def +++ b/common/networking/packets.def @@ -543,6 +543,7 @@ PACKET_GAME_INFO = 16; sc, is-info BOOL killcitizen; BOOL killstack; BOOL only_killing_makes_veteran; + BOOL only_real_fight_makes_veteran; UINT8 nuke_pop_loss_pct; UINT8 nuke_defender_survival_chance_pct; UINT16 min_city_center_output[O_LAST]; diff --git a/data/alien/game.ruleset b/data/alien/game.ruleset index 78b0f3c8ef..5589e60210 100644 --- a/data/alien/game.ruleset +++ b/data/alien/game.ruleset @@ -233,6 +233,12 @@ tired_attack = TRUE ; Set this to TRUE if unit should never gain veterancy from such a combat. only_killing_makes_veteran = FALSE +; If either side of the fight is completely powerless, i.e., has +; zero attack/defense power after modifiers, fight is not considered +; a real fight. If this setting is enabled, nobody gets made veteran after +; such a fight. +only_real_fight_makes_veteran = FALSE + ; Percentage of population lost by a city after nuclear attak. If set to ; 100 city is destroyed along with all the units. If set to 0 city does not ; loose population. Any value below 50 means the city can never be diff --git a/data/civ1/game.ruleset b/data/civ1/game.ruleset index bc65d632dc..0f3604874a 100644 --- a/data/civ1/game.ruleset +++ b/data/civ1/game.ruleset @@ -221,6 +221,12 @@ tired_attack = TRUE ; Set this to TRUE if unit should never gain veterancy from such a combat. only_killing_makes_veteran = FALSE +; If either side of the fight is completely powerless, i.e., has +; zero attack/defense power after modifiers, fight is not considered +; a real fight. If this setting is enabled, nobody gets made veteran after +; such a fight. +only_real_fight_makes_veteran = FALSE + ; Percentage of population lost by a city after nuclear attak. If set to ; 100 city is destroyed along with all the units. If set to 0 city does not ; loose population. Any value below 50 means the city can never be diff --git a/data/civ2/game.ruleset b/data/civ2/game.ruleset index e9c6c17d48..73909d3c7b 100644 --- a/data/civ2/game.ruleset +++ b/data/civ2/game.ruleset @@ -217,6 +217,12 @@ tired_attack = TRUE ; Set this to TRUE if unit should never gain veterancy from such a combat. only_killing_makes_veteran = FALSE +; If either side of the fight is completely powerless, i.e., has +; zero attack/defense power after modifiers, fight is not considered +; a real fight. If this setting is enabled, nobody gets made veteran after +; such a fight. +only_real_fight_makes_veteran = FALSE + ; Percentage of population lost by a city after nuclear attak. If set to ; 100 city is destroyed along with all the units. If set to 0 city does not ; loose population. Any value below 50 means the city can never be diff --git a/data/civ2civ3/game.ruleset b/data/civ2civ3/game.ruleset index 9cbf672530..50292d1b16 100644 --- a/data/civ2civ3/game.ruleset +++ b/data/civ2civ3/game.ruleset @@ -239,6 +239,12 @@ tired_attack = TRUE ; Set this to TRUE if unit should never gain veterancy from such a combat. only_killing_makes_veteran = FALSE +; If either side of the fight is completely powerless, i.e., has +; zero attack/defense power after modifiers, fight is not considered +; a real fight. If this setting is enabled, nobody gets made veteran after +; such a fight. +only_real_fight_makes_veteran = FALSE + ; Percentage of population lost by a city after nuclear attak. If set to ; 100 city is destroyed along with all the units. If set to 0 city does not ; loose population. Any value below 50 means the city can never be diff --git a/data/classic/game.ruleset b/data/classic/game.ruleset index 58e959fdcd..bdd6dc054c 100644 --- a/data/classic/game.ruleset +++ b/data/classic/game.ruleset @@ -234,6 +234,12 @@ tired_attack = FALSE ; Set this to TRUE if unit should never gain veterancy from such a combat. only_killing_makes_veteran = FALSE +; If either side of the fight is completely powerless, i.e., has +; zero attack/defense power after modifiers, fight is not considered +; a real fight. If this setting is enabled, nobody gets made veteran after +; such a fight. +only_real_fight_makes_veteran = FALSE + ; Percentage of population lost by a city after nuclear attak. If set to ; 100 city is destroyed along with all the units. If set to 0 city does not ; loose population. Any value below 50 means the city can never be diff --git a/data/goldkeep/game.ruleset b/data/goldkeep/game.ruleset index 02aa716c8a..59c8f2f080 100644 --- a/data/goldkeep/game.ruleset +++ b/data/goldkeep/game.ruleset @@ -237,6 +237,12 @@ tired_attack = FALSE ; Set this to TRUE if unit should never gain veterancy from such a combat. only_killing_makes_veteran = FALSE +; If either side of the fight is completely powerless, i.e., has +; zero attack/defense power after modifiers, fight is not considered +; a real fight. If this setting is enabled, nobody gets made veteran after +; such a fight. +only_real_fight_makes_veteran = FALSE + ; Percentage of population lost by a city after nuclear attak. If set to ; 100 city is destroyed along with all the units. If set to 0 city does not ; loose population. Any value below 50 means the city can never be diff --git a/data/granularity/game.ruleset b/data/granularity/game.ruleset index 3273956dca..6c4aeb211e 100644 --- a/data/granularity/game.ruleset +++ b/data/granularity/game.ruleset @@ -229,6 +229,12 @@ tired_attack = FALSE ; Set this to TRUE if unit should never gain veterancy from such a combat. only_killing_makes_veteran = FALSE +; If either side of the fight is completely powerless, i.e., has +; zero attack/defense power after modifiers, fight is not considered +; a real fight. If this setting is enabled, nobody gets made veteran after +; such a fight. +only_real_fight_makes_veteran = FALSE + ; Percentage of population lost by a city after nuclear attak. If set to ; 100 city is destroyed along with all the units. If set to 0 city does not ; loose population. Any value below 50 means the city can never be diff --git a/data/multiplayer/game.ruleset b/data/multiplayer/game.ruleset index 11b818160b..140500afd8 100644 --- a/data/multiplayer/game.ruleset +++ b/data/multiplayer/game.ruleset @@ -237,6 +237,12 @@ tired_attack = TRUE ; Set this to TRUE if unit should never gain veterancy from such a combat. only_killing_makes_veteran = FALSE +; If either side of the fight is completely powerless, i.e., has +; zero attack/defense power after modifiers, fight is not considered +; a real fight. If this setting is enabled, nobody gets made veteran after +; such a fight. +only_real_fight_makes_veteran = FALSE + ; Percentage of population lost by a city after nuclear attak. If set to ; 100 city is destroyed along with all the units. If set to 0 city does not ; loose population. Any value below 50 means the city can never be diff --git a/data/ruledit/comments-3.2.txt b/data/ruledit/comments-3.2.txt index 4cb940627e..93d86f52c1 100644 --- a/data/ruledit/comments-3.2.txt +++ b/data/ruledit/comments-3.2.txt @@ -1270,6 +1270,13 @@ only_killing_makes_veteran = "\n\ ; Set this to TRUE if unit should never gain veterancy from such a combat.\ " +only_real_fight_makes_veteran = "\n\ +; If either side of the fight is completely powerless, i.e., has\n\ +; zero attack/defense power after modifiers, fight is not considered\n\ +; a real fight. If this setting is enabled, nobody gets made veteran after\n\ +; such a fight.\ +" + nuke_pop_loss_pct = "\n\ ; Percentage of population lost by a city after nuclear attak. If set to\n\ ; 100 city is destroyed along with all the units. If set to 0 city does not\n\ diff --git a/data/sandbox/game.ruleset b/data/sandbox/game.ruleset index c7e67b1c15..3a44053baf 100644 --- a/data/sandbox/game.ruleset +++ b/data/sandbox/game.ruleset @@ -237,6 +237,12 @@ tired_attack = TRUE ; Set this to TRUE if unit should never gain veterancy from such a combat. only_killing_makes_veteran = FALSE +; If either side of the fight is completely powerless, i.e., has +; zero attack/defense power after modifiers, fight is not considered +; a real fight. If this setting is enabled, nobody gets made veteran after +; such a fight. +only_real_fight_makes_veteran = FALSE + ; Percentage of population lost by a city after nuclear attak. If set to ; 100 city is destroyed along with all the units. If set to 0 city does not ; loose population. Any value below 50 means the city can never be diff --git a/data/stub/game.ruleset b/data/stub/game.ruleset index 534a0552de..d2540e4521 100644 --- a/data/stub/game.ruleset +++ b/data/stub/game.ruleset @@ -221,6 +221,12 @@ tired_attack = FALSE ; Set this to TRUE if unit should never gain veterancy from such a combat. only_killing_makes_veteran = FALSE +; If either side of the fight is completely powerless, i.e., has +; zero attack/defense power after modifiers, fight is not considered +; a real fight. If this setting is enabled, nobody gets made veteran after +; such a fight. +only_real_fight_makes_veteran = FALSE + ; Percentage of population lost by a city after nuclear attak. If set to ; 100 city is destroyed along with all the units. If set to 0 city does not ; loose population. Any value below 50 means the city can never be diff --git a/data/webperimental/game.ruleset b/data/webperimental/game.ruleset index 97673c95f2..e658ea748a 100644 --- a/data/webperimental/game.ruleset +++ b/data/webperimental/game.ruleset @@ -238,6 +238,12 @@ tired_attack = FALSE ; Set this to TRUE if unit should never gain veterancy from such a combat. only_killing_makes_veteran = FALSE +; If either side of the fight is completely powerless, i.e., has +; zero attack/defense power after modifiers, fight is not considered +; a real fight. If this setting is enabled, nobody gets made veteran after +; such a fight. +only_real_fight_makes_veteran = FALSE + ; Percentage of population lost by a city after nuclear attak. If set to ; 100 city is destroyed along with all the units. If set to 0 city does not ; loose population. Any value below 50 means the city can never be diff --git a/fc_version b/fc_version index dd5728dd04..2e236e07bd 100755 --- a/fc_version +++ b/fc_version @@ -56,7 +56,7 @@ DEFAULT_FOLLOW_TAG=S3_2 # - No new mandatory capabilities can be added to the release branch; doing # so would break network capability of supposedly "compatible" releases. # -NETWORK_CAPSTRING="+Freeciv.Devel-3.2-2021.Oct.09" +NETWORK_CAPSTRING="+Freeciv.Devel-3.2-2021.Oct.19" FREECIV_DISTRIBUTOR="" diff --git a/server/ruleset.c b/server/ruleset.c index 0c4699c3a0..062a0c3af9 100644 --- a/server/ruleset.c +++ b/server/ruleset.c @@ -6977,6 +6977,10 @@ static bool load_ruleset_game(struct section_file *file, bool act, = secfile_lookup_bool_default(file, RS_DEFAULT_ONLY_KILLING_VETERAN, "combat_rules.only_killing_makes_veteran"); + game.info.only_real_fight_makes_veteran + = secfile_lookup_bool_default(file, RS_DEFAULT_ONLY_REAL_FIGHT_VETERAN, + "combat_rules.only_real_fight_makes_veteran"); + game.info.nuke_pop_loss_pct = secfile_lookup_int_default_min_max(file, RS_DEFAULT_NUKE_POP_LOSS_PCT, RS_MIN_NUKE_POP_LOSS_PCT, diff --git a/server/ruleset.h b/server/ruleset.h index ce8f1e2786..ad179b0ddf 100644 --- a/server/ruleset.h +++ b/server/ruleset.h @@ -98,6 +98,9 @@ int ruleset_purge_redundant_reqs(void); #define RS_DEFAULT_EXTRA_APPEARANCE 15 #define RS_DEFAULT_EXTRA_DISAPPEARANCE 15 +#define RS_DEFAULT_ONLY_KILLING_VETERAN FALSE +#define RS_DEFAULT_ONLY_REAL_FIGHT_VETERAN FALSE + #define RS_DEFAULT_SMALL_WONDER_VISIBILITY "Always" #ifdef __cplusplus diff --git a/server/unithand.c b/server/unithand.c index 326e27809f..d1c02e450f 100644 --- a/server/unithand.c +++ b/server/unithand.c @@ -4643,6 +4643,7 @@ static bool do_attack(struct unit *punit, struct tile *def_tile, int def_power, att_power; struct unit *pdefender; const struct unit_type *act_utype = unit_type_get(punit); + bool powerless; if (!(pdefender = get_defender(punit, def_tile, paction))) { /* Can't fight air... */ @@ -4698,7 +4699,7 @@ static bool do_attack(struct unit *punit, struct tile *def_tile, /* Record tired attack string before attack */ sz_strlcpy(attacker_tired, unit_tired_attack_string(punit)); - unit_versus_unit(punit, pdefender, &att_hp, &def_hp, paction); + powerless = unit_versus_unit(punit, pdefender, &att_hp, &def_hp, paction); if ((att_hp <= 0 || utype_is_consumed_by_action(paction, punit->utype)) && unit_transported(punit)) { @@ -4711,7 +4712,7 @@ static bool do_attack(struct unit *punit, struct tile *def_tile, punit->hp = att_hp; pdefender->hp = def_hp; - combat_veterans(punit, pdefender); + combat_veterans(punit, pdefender, powerless); /* Adjust attackers moves_left _after_ unit_versus_unit() so that * the movement attack modifier is correct! --dwp diff --git a/server/unittools.c b/server/unittools.c index 1b9124e737..e427b0baae 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -271,8 +271,10 @@ static bool maybe_become_veteran_real(struct unit *punit, bool settler) EFT_COMBAT_ROUNDS rounds have been fought. 3) the aftermath, the loser (and potentially the stack which is below it) is wiped, and the winner gets a chance of gaining veteran status + + Returns whether either side was completely powerless. **************************************************************************/ -void unit_versus_unit(struct unit *attacker, struct unit *defender, +bool unit_versus_unit(struct unit *attacker, struct unit *defender, int *att_hp, int *def_hp, const struct action *paction) { @@ -318,6 +320,8 @@ void unit_versus_unit(struct unit *attacker, struct unit *defender, if (*def_hp < 0) { *def_hp = 0; } + + return attackpower <= 0 || defensepower <= 0; } /**********************************************************************//** @@ -367,17 +371,21 @@ void unit_bombs_unit(struct unit *attacker, struct unit *defender, } /**********************************************************************//** - Maybe make either side of combat veteran + Maybe make either side of combat veteran. + Powerless means that either side of the combat was completely powerless. **************************************************************************/ -void combat_veterans(struct unit *attacker, struct unit *defender) +void combat_veterans(struct unit *attacker, struct unit *defender, + bool powerless) { - if (attacker->hp <= 0 || defender->hp <= 0 - || !game.info.only_killing_makes_veteran) { - if (attacker->hp > 0) { - maybe_make_veteran(attacker); - } - if (defender->hp > 0) { - maybe_make_veteran(defender); + if (!powerless || !game.info.only_real_fight_makes_veteran) { + if (attacker->hp <= 0 || defender->hp <= 0 + || !game.info.only_killing_makes_veteran) { + if (attacker->hp > 0) { + maybe_make_veteran(attacker); + } + if (defender->hp > 0) { + maybe_make_veteran(defender); + } } } } diff --git a/server/unittools.h b/server/unittools.h index 21ad492997..2199c1e7f8 100644 --- a/server/unittools.h +++ b/server/unittools.h @@ -76,13 +76,14 @@ struct unit_type *find_a_unit_type(enum unit_role_id role, enum unit_role_id role_tech); bool maybe_make_veteran(struct unit *punit); void notify_unit_experience(struct unit *punit); -void unit_versus_unit(struct unit *attacker, struct unit *defender, +bool unit_versus_unit(struct unit *attacker, struct unit *defender, int *att_hp, int *def_hp, const struct action *paction); void unit_bombs_unit(struct unit *attacker, struct unit *defender, int *att_hp, int *def_hp, const struct action *paction); -void combat_veterans(struct unit *attacker, struct unit *defender); +void combat_veterans(struct unit *attacker, struct unit *defender, + bool powerless); /* move check related */ bool is_unit_being_refueled(const struct unit *punit); diff --git a/tools/ruleutil/comments.c b/tools/ruleutil/comments.c index 9f37b39547..3475a7e112 100644 --- a/tools/ruleutil/comments.c +++ b/tools/ruleutil/comments.c @@ -60,6 +60,7 @@ static struct { char *incite_cost; char *combat_rules_tired_attack; char *combat_rules_only_killing_veteran; + char *combat_rules_only_real_fight_veteran; char *combat_rules_nuke_pop_loss; char *combat_rules_nuke_defender_survival; char *auto_attack; @@ -160,6 +161,8 @@ bool comments_load(void) "entrydoc.tired_attack"); comment_load(comments_storage.combat_rules_only_killing_veteran, comment_file, "entrydoc.only_killing_makes_veteran"); + comment_load(comments_storage.combat_rules_only_real_fight_veteran, comment_file, + "entrydoc.only_real_fight_makes_veteran"); comment_load(comments_storage.combat_rules_nuke_pop_loss, comment_file, "entrydoc.nuke_pop_loss_pct"); comment_load(comments_storage.combat_rules_nuke_defender_survival, @@ -509,6 +512,16 @@ void comment_combat_rules_only_killing_veteran(struct section_file *sfile) "combat_rules"); } +/**********************************************************************//** + Write combat_rules only_real_fight_makes_veteran settings header. +**************************************************************************/ +void comment_combat_rules_only_real_fight_veteran(struct section_file *sfile) +{ + comment_entry_write(sfile, + comments_storage.combat_rules_only_real_fight_veteran, + "combat_rules"); +} + /**********************************************************************//** Write combat_rules nuke_pop_loss_pct settings header. **************************************************************************/ diff --git a/tools/ruleutil/comments.h b/tools/ruleutil/comments.h index 8fc997c90b..ffccb8ffa8 100644 --- a/tools/ruleutil/comments.h +++ b/tools/ruleutil/comments.h @@ -63,6 +63,7 @@ void comment_wonder_visibility_small_wonders(struct section_file *sfile); void comment_incite_cost(struct section_file *sfile); void comment_combat_rules_tired_attack(struct section_file *sfile); void comment_combat_rules_only_killing_veteran(struct section_file *sfile); +void comment_combat_rules_only_real_fight_veteran(struct section_file *sfile); void comment_combat_rules_nuke_pop_loss(struct section_file *sfile); void comment_combat_rules_nuke_defender_survival(struct section_file *sfile); void comment_auto_attack(struct section_file *sfile); diff --git a/tools/ruleutil/rulesave.c b/tools/ruleutil/rulesave.c index 7072500456..9f85f7dafb 100644 --- a/tools/ruleutil/rulesave.c +++ b/tools/ruleutil/rulesave.c @@ -1393,6 +1393,12 @@ static bool save_game_ruleset(const char *filename, const char *name) save_default_bool(sfile, game.info.only_killing_makes_veteran, RS_DEFAULT_ONLY_KILLING_VETERAN, "combat_rules.only_killing_makes_veteran", NULL); + if (game.info.only_real_fight_makes_veteran != RS_DEFAULT_ONLY_REAL_FIGHT_VETERAN) { + comment_combat_rules_only_real_fight_veteran(sfile); + } + save_default_bool(sfile, game.info.only_real_fight_makes_veteran, + RS_DEFAULT_ONLY_REAL_FIGHT_VETERAN, + "combat_rules.only_real_fight_makes_veteran", NULL); if (game.info.nuke_pop_loss_pct != RS_DEFAULT_NUKE_POP_LOSS_PCT) { comment_combat_rules_nuke_pop_loss(sfile); } -- 2.33.0