I looked into the source code, namely /common/combat.c and I'm wondering is the hardcoded defense bonus for units in cities only present in the function defense_multiplication - because if so, then hopefully this may be a simple enough fix although probably would need some refining such as making it a server option to whether cities should automatically grant fortification to units that can fortify or should the units actually need to be commanded to do so - along with the ruleset specific bonus given for fortification. Since I'm not sure how server options work nor how rulesets are actually read, beyond some light snooping - I think its out of my scope to offer anything useful in that area.
What the solution presented does is simply compare the Defend_bonus effect against the currently hardcoded fortification bonus, only applying the highest one. In the case of a city with walls, the effect bonus is only applied - in cases where the ruleset only applies say an extra 10% to defense - the fortification bonus is only applied. Basically the better bonus is applied, I'm curious to whether there are any glaring problems that others might find too.
Code: Select all
static int defense_multiplication(const struct unit_type *att_type,
const struct unit_type *def_type,
const struct player *def_player,
const struct tile *ptile,
int defensepower, bool fortified)
{
struct city *pcity = tile_city(ptile);
int mod = 100;
fc_assert_ret_val(NULL != def_type, 0);
if (NULL != att_type) {
int defense_divider;
int defense_multiplier = 1 + combat_bonus_against(def_type->bonuses, att_type,
CBONUS_DEFENSE_MULTIPLIER);
defensepower *= defense_multiplier;
if (!utype_has_flag(att_type, UTYF_IGWALL)) {
/* This applies even if pcity is NULL. */
mod = 100 + get_unittype_bonus(def_player, ptile,
att_type, EFT_DEFEND_BONUS);
}
defense_divider = 1 + combat_bonus_against(att_type->bonuses, def_type,
CBONUS_DEFENSE_DIVIDER);
defensepower /= defense_divider;
}
defensepower +=
defensepower * tile_extras_defense_bonus(ptile, def_type) / 100;
if ((pcity || fortified)
&& uclass_has_flag(utype_class(def_type), UCF_CAN_FORTIFY)) {
defensepower = MAX(((defensepower * 3) / 2), (defensepower * mod / 100));
} else {
defensepower = MAX(0, defensepower * mod / 100);
}
return defensepower;
}