From 56627ed7af84f0aac74873898f2dd718682cd2a3 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 9 Oct 2021 18:49:44 +0300 Subject: [PATCH 37/37] 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/experimental/game.ruleset | 6 ++++++ data/granularity/game.ruleset | 6 ++++++ data/multiplayer/game.ruleset | 6 ++++++ 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/rulesave.c | 3 +++ 20 files changed, 102 insertions(+), 16 deletions(-) diff --git a/common/game.h b/common/game.h index 846cbf257b..424b4ba0ef 100644 --- a/common/game.h +++ b/common/game.h @@ -826,7 +826,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 e8c7529051..d2d5138057 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 83437c523a..945145b5ec 100644 --- a/data/alien/game.ruleset +++ b/data/alien/game.ruleset @@ -232,6 +232,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 4aeb6126d0..555d590418 100644 --- a/data/civ1/game.ruleset +++ b/data/civ1/game.ruleset @@ -220,6 +220,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 9705997b96..86bc6be159 100644 --- a/data/civ2/game.ruleset +++ b/data/civ2/game.ruleset @@ -216,6 +216,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 0db66348f5..8cec1566d8 100644 --- a/data/civ2civ3/game.ruleset +++ b/data/civ2civ3/game.ruleset @@ -238,6 +238,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 c39bb27f36..ee40ee7625 100644 --- a/data/classic/game.ruleset +++ b/data/classic/game.ruleset @@ -233,6 +233,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/experimental/game.ruleset b/data/experimental/game.ruleset index e4a4dce934..8c731ec554 100644 --- a/data/experimental/game.ruleset +++ b/data/experimental/game.ruleset @@ -241,6 +241,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 26ccc663b2..31f80b87e4 100644 --- a/data/granularity/game.ruleset +++ b/data/granularity/game.ruleset @@ -228,6 +228,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 5972023628..4f422ef9f1 100644 --- a/data/multiplayer/game.ruleset +++ b/data/multiplayer/game.ruleset @@ -236,6 +236,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/sandbox/game.ruleset b/data/sandbox/game.ruleset index 6cc7a8d61a..8546308fa5 100644 --- a/data/sandbox/game.ruleset +++ b/data/sandbox/game.ruleset @@ -236,6 +236,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 cf9ab79805..f1bd288ac4 100644 --- a/data/stub/game.ruleset +++ b/data/stub/game.ruleset @@ -220,6 +220,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 bfda05af50..1438728ee8 100644 --- a/data/webperimental/game.ruleset +++ b/data/webperimental/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/fc_version b/fc_version index 13e07b847b..e0bfc89b1e 100755 --- a/fc_version +++ b/fc_version @@ -56,7 +56,7 @@ DEFAULT_FOLLOW_TAG=S3_1 # - 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.1-2021.Oct.03" +NETWORK_CAPSTRING="+Freeciv.Devel-3.1-2021.Oct.09" FREECIV_DISTRIBUTOR="" diff --git a/server/ruleset.c b/server/ruleset.c index b866058f74..42329085d7 100644 --- a/server/ruleset.c +++ b/server/ruleset.c @@ -7321,6 +7321,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 e9a230dda2..c126e8003d 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 66daaf4aa1..96f9c5c598 100644 --- a/server/unithand.c +++ b/server/unithand.c @@ -4437,6 +4437,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))) { /* Can't fight air... */ @@ -4492,7 +4493,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); + powerless = unit_versus_unit(punit, pdefender, &att_hp, &def_hp); if ((att_hp <= 0 || utype_is_consumed_by_action(paction, punit->utype)) && unit_transported(punit)) { @@ -4505,7 +4506,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 75d68fd24d..2e06b892d8 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) { int attackpower = get_total_attack_power(attacker, defender); @@ -317,6 +319,8 @@ void unit_versus_unit(struct unit *attacker, struct unit *defender, if (*def_hp < 0) { *def_hp = 0; } + + return attackpower <= 0 || defensepower <= 0; } /**********************************************************************//** @@ -361,17 +365,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 1eb7169193..a65fa8bb43 100644 --- a/server/unittools.h +++ b/server/unittools.h @@ -76,11 +76,12 @@ 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); void unit_bombs_unit(struct unit *attacker, struct unit *defender, int *att_hp, int *def_hp); -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/rulesave.c b/tools/ruleutil/rulesave.c index 5065694081..b4598e8309 100644 --- a/tools/ruleutil/rulesave.c +++ b/tools/ruleutil/rulesave.c @@ -1363,6 +1363,9 @@ 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); + 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); save_default_int(sfile, game.info.nuke_pop_loss_pct, RS_DEFAULT_NUKE_POP_LOSS_PCT, "combat_rules.nuke_pop_loss_pct", NULL); -- 2.33.0