[Freeciv-Dev] (PR#14314) effects and unitclass cleanup
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=14314 >
This patch (which includes 14277) merges all class-based effects into
single effects.
EFT_SEA_MOVE -> EFT_MOVE_BONUS
EFT_*_VETERAN and EFT_VETERAN_DIPLOMATS -> EFT_VETERAN_BUILD
EFT_LAND_VET_COMBAT -> EFT_VETERAN_COMBAT
EFT_*_REGEN -> EFT_HP_REGEN
EFT_*_DEFEND -> EFT_DEFEND_BONUS
I also merged in fortress HP regeneration and tweaked the HP regen code
to scale better. This could be modified to be even more effect-based.
There are some bits of ugliness since many of these effects were not
truly class-based. Air effects in particular often applied to air and
helicopter and occasionally to missile units. I updated all this in the
ruleset but I might have missed something.
A whole set of functions that accepted unittype+tile now has to accept
unittype+tile+owner. This is because the owner may affect the unit
values now (with player-wide or nation effects).
I only updated the default ruleset.
Also, the AI code needs attention.
-jason
Index: doc/README.effects
===================================================================
--- doc/README.effects (revision 11124)
+++ doc/README.effects (working copy)
@@ -88,6 +88,9 @@
"Incite_Cost_Pct" - increases revolt cost by AMOUNT percent
+"Defend_Bonus" - Increases defensive bonuses of units. Any unit requirements
+ on this effect will be applied to the _attacking_ unit.
+
"Size_Adj" - Increases maximum city size by AMOUNT
"Size_Unlimit" - Removes maximum city size limitation
Index: server/gotohand.c
===================================================================
--- server/gotohand.c (revision 11124)
+++ server/gotohand.c (working copy)
@@ -912,7 +912,8 @@
struct tile *dest_tile)
{
#define UNIT_DEFENSE(punit, ptile, defence_multiplier) \
- ((get_virtual_defense_power(NULL, (punit)->type, (ptile), FALSE, 0) * \
+ ((get_virtual_defense_power(NULL, (punit)->type, (punit)->owner, \
+ (ptile), FALSE, 0) * \
(defence_multiplier)) / 2)
#define UNIT_RATING(punit, ptile, defence_multiplier) \
@@ -1017,12 +1018,9 @@
*/
defence_multiplier = 2;
if (pcity) {
- /* This isn't very accurate. */
- defence_multiplier += (get_city_bonus(pcity, EFT_LAND_DEFEND)
- + get_city_bonus(pcity, EFT_MISSILE_DEFEND)
- + get_city_bonus(pcity, EFT_AIR_DEFEND)
- + get_city_bonus(pcity, EFT_SEA_DEFEND)) / 100;
+ defence_multiplier += get_city_bonus(pcity, EFT_DEFEND_BONUS) / 100;
}
+ defence_multiplier = MAX(1, defence_multiplier); /* no division by 0 */
/*
* Find the best ally unit at the target tile.
Index: server/citytools.c
===================================================================
--- server/citytools.c (revision 11124)
+++ server/citytools.c (working copy)
@@ -478,17 +478,10 @@
|| unit_type_flag(punittype, F_CITIES)) {
return 0;
}
-
- if (unit_type_flag(punittype, F_DIPLOMAT)) {
- return (get_city_bonus(pcity, EFT_VETERAN_DIPLOMATS) ? 1 : 0);
- } else if (is_ground_unittype(punittype)) {
- return (get_city_bonus(pcity, EFT_LAND_VETERAN) > 0) ? 1 : 0;
- } else {
- if (is_sailing_unittype(punittype)) {
- return (get_city_bonus(pcity, EFT_SEA_VETERAN) > 0) ? 1 : 0;
- } else {
- return (get_city_bonus(pcity, EFT_AIR_VETERAN) > 0) ? 1 : 0;
- }
+
+ if (get_unittype_bonus(pcity->owner, pcity->tile, punittype,
+ EFT_VETERAN_BUILD) > 0) {
+ return 1;
}
return 0;
Index: server/unittools.c
===================================================================
--- server/unittools.c (revision 11124)
+++ server/unittools.c (working copy)
@@ -163,12 +163,9 @@
|| unit_flag(punit, F_NO_VETERAN)) {
return FALSE;
} else {
- int mod = 100;
+ int mod = 100 + get_unittype_bonus(punit->owner, punit->tile,
+ punit->type, EFT_VETERAN_COMBAT);
- if (is_ground_unittype(punit->type)) {
- mod += get_unit_bonus(punit, EFT_LAND_VET_COMBAT);
- }
-
/* The modification is tacked on as a multiplier to the base chance.
* For example with a base chance of 50% for green units and a modifier
* of +50% the end chance is 75%. */
@@ -530,34 +527,25 @@
***************************************************************************/
static int hp_gain_coord(struct unit *punit)
{
- int hp;
- struct city *pcity;
- struct unit_class *class = get_unit_class(punit->type);
+ int hp = 0;
+ const int base = unit_type(punit)->hp;
- if (unit_on_fortress(punit))
- hp=unit_type(punit)->hp/4;
- else
- hp=0;
- if((pcity=tile_get_city(punit->tile))) {
- if ((get_city_bonus(pcity, EFT_LAND_REGEN) > 0
- && is_ground_unit(punit))
- || (get_city_bonus(pcity, EFT_AIR_REGEN) > 0
- && (is_air_unit(punit) || is_heli_unit(punit)))
- || (get_city_bonus(pcity, EFT_SEA_REGEN) > 0
- && is_sailing_unit(punit))) {
- hp=unit_type(punit)->hp;
- }
- else
- hp=unit_type(punit)->hp/3;
+ /* Includes barracks (100%), fortress (25%), etc. */
+ hp += base * get_unit_bonus(punit, EFT_HP_REGEN) / 100;
+
+ if (punit->tile->city) {
+ hp = MAX(hp, base / 3);
}
- else if (!class->hp_loss_pct) {
- hp++;
+
+ if (!punit->type->class->hp_loss_pct) {
+ hp += (base + 9) / 10;
}
- if(punit->activity==ACTIVITY_FORTIFIED)
- hp++;
-
- return hp;
+ if (punit->activity == ACTIVITY_FORTIFIED) {
+ hp += (base + 9) / 10;
+ }
+
+ return MAX(hp, 0);
}
/**************************************************************************
@@ -989,7 +977,10 @@
continue;
if (unit_list_size(ptile->units) > 0)
continue;
- value = get_virtual_defense_power(NULL, u_type, ptile, FALSE, 0);
+
+ /* City has not changed hands yet; see place_partisans(). */
+ value = get_virtual_defense_power(NULL, u_type, pcity->owner,
+ ptile, FALSE, 0);
value *= 10;
if (ptile->continent != tile_get_continent(pcity->tile)) {
Index: data/civ1/effects.ruleset
===================================================================
--- data/civ1/effects.ruleset (revision 11124)
+++ data/civ1/effects.ruleset (working copy)
@@ -433,23 +433,26 @@
}
[effect_city_walls]
-name = "Land_Defend"
+name = "Defend_Bonus"
value = 200
reqs =
{ "type", "name", "range"
"Building", "City Walls", "City"
+ "UnitClass", "Land", "Local"
}
nreqs =
{ "type", "name", "range"
"Building", "Great Wall", "Player"
}
+; No helicoptors in civ1
[effect_city_walls_1]
-name = "Sea_Defend"
+name = "Defend_Bonus"
value = 200
reqs =
{ "type", "name", "range"
"Building", "City Walls", "City"
+ "UnitClass", "Sea", "Local"
}
nreqs =
{ "type", "name", "range"
@@ -820,19 +823,21 @@
}
[effect_great_wall]
-name = "Land_Defend"
+name = "Defend_Bonus"
value = 200
reqs =
{ "type", "name", "range"
"Building", "Great Wall", "Player"
+ "UnitClass", "Land", "Local"
}
[effect_great_wall_1]
-name = "Sea_Defend"
+name = "Defend_Bonus"
value = 200
reqs =
{ "type", "name", "range"
"Building", "Great Wall", "Player"
+ "UnitClass", "Sea", "Local"
}
[effect_hanging_gardens]
Index: data/civ2/effects.ruleset
===================================================================
--- data/civ2/effects.ruleset (revision 11124)
+++ data/civ2/effects.ruleset (working copy)
@@ -541,17 +541,31 @@
}
[effect_city_walls]
-name = "Land_Defend"
+name = "Defend_Bonus"
value = 200
reqs =
{ "type", "name", "range"
"Building", "City Walls", "City"
+ "UnitClass", "Land", "Local"
}
nreqs =
{ "type", "name", "range"
"Building", "Great Wall", "Player"
}
+[effect_city_walls]
+name = "Defend_Bonus"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "City Walls", "City"
+ "UnitClass", "Helicopter", "Local"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
[effect_city_walls_1]
name = "Unit_No_Lose_Pop"
value = 1
@@ -561,11 +575,12 @@
}
[effect_coastal_defense]
-name = "Sea_Defend"
+name = "Defend_Bonus"
value = 100
reqs =
{ "type", "name", "range"
"Building", "Coastal Defense", "City"
+ "UnitClass", "Sea", "Local"
}
[effect_colosseum]
@@ -938,11 +953,12 @@
}
[effect_sam_battery]
-name = "Air_Defend"
+name = "Defend_Bonus"
value = 100
reqs =
{ "type", "name", "range"
"Building", "SAM Battery", "City"
+ "UnitClass", "Air", "Local"
}
[effect_sdi_defense]
@@ -954,11 +970,12 @@
}
[effect_sdi_defense_1]
-name = "Missile_Defend"
+name = "Defend_Bonus"
value = 100
reqs =
{ "type", "name", "range"
"Building", "SDI Defense", "City"
+ "UnitClass", "Missile", "Local"
}
[effect_sewer_system]
@@ -1128,13 +1145,23 @@
}
[effect_great_wall]
-name = "Land_Defend"
+name = "Defend_Bonus"
value = 200
reqs =
{ "type", "name", "range"
"Building", "Great Wall", "Player"
+ "UnitClass", "Land", "Local"
}
+[effect_great_wall]
+name = "Defend_Bonus"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ "UnitClass", "Helicopter", "Local"
+ }
+
[effect_great_wall_1]
name = "Unit_No_Lose_Pop"
value = 1
Index: data/default/effects.ruleset
===================================================================
--- data/default/effects.ruleset (revision 11124)
+++ data/default/effects.ruleset (working copy)
@@ -56,6 +56,16 @@
}
+; Fortress HP regen
+[effect_fortress_hp_regen]
+name = "HP_Regen"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Special", "Fortress", "Tile"
+ "UnitClass", "Land", "Local"
+ }
+
; Base vision range - radius of vision is sqrt(5) = 2.24
[effect_city_vision]
name = "City_Vision_Radius_Sq"
@@ -64,11 +74,12 @@
; Nuclear power gives +1 moves to sea units
[effect_nuclear_powered_boats]
-name = "Sea_Move"
+name = "Move_Bonus"
value = 1
reqs =
{ "type", "name", "range"
"Tech", "Nuclear Power", "Player"
+ "UnitClass", "Sea", "Local"
}
[effect_civil_war_0]
@@ -345,11 +356,12 @@
}
[effect_communism_0]
-name = "Veteran_Diplomats"
+name = "Veteran_Build"
value = 1
reqs =
{ "type", "name", "range"
"Gov", "Communism", "Player"
+ "UnitFlag", "Diplomat", "Local"
}
[effect_revolution_0]
@@ -397,21 +409,50 @@
}
[effect_airport]
-name = "Air_Veteran"
+name = "Veteran_Build"
value = 1
reqs =
{ "type", "name", "range"
"Building", "Airport", "City"
+ "UnitClass", "Air", "Local"
}
-[effect_airport_1]
-name = "Air_Regen"
+[effect_airport_0a]
+name = "Veteran_Build"
value = 1
reqs =
{ "type", "name", "range"
"Building", "Airport", "City"
+ "UnitClass", "Helicoptor", "Local"
}
+[effect_airport_0a]
+name = "Veteran_Build"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Airport", "City"
+ "UnitClass", "Missile", "Local"
+ }
+
+[effect_airport_1]
+name = "HP_Regen"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "Airport", "City"
+ "UnitClass", "Air", "Local"
+ }
+
+[effect_airport_1a]
+name = "HP_Regen"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "Airport", "City"
+ "UnitClass", "Helicopter", "Local"
+ }
+
[effect_airport_2]
name = "Airlift"
value = 1
@@ -454,51 +495,69 @@
}
[effect_barracks]
-name = "Land_Veteran"
+name = "Veteran_Build"
value = 1
reqs =
{ "type", "name", "range"
"Building", "Barracks", "City"
+ "UnitClass", "Land", "Local"
}
+nreqs =
+ { "type", "name", "range"
+ "UnitFlag", "Diplomat", "Local"
+ }
[effect_barracks_1]
-name = "Land_Regen"
-value = 1
+name = "HP_Regen"
+value = 100
reqs =
{ "type", "name", "range"
"Building", "Barracks", "City"
+ "UnitClass", "Land", "Local"
}
[effect_barracks_ii]
-name = "Land_Veteran"
+name = "Veteran_Build"
value = 1
reqs =
{ "type", "name", "range"
"Building", "Barracks II", "City"
+ "UnitClass", "Land", "Local"
}
+nreqs =
+ { "type", "name", "range"
+ "UnitFlag", "Diplomat", "Local"
+ }
[effect_barracks_ii_1]
-name = "Land_Regen"
-value = 1
+name = "HP_Regen"
+value = 100
reqs =
{ "type", "name", "range"
"Building", "Barracks II", "City"
+ "UnitClass", "Land", "Local"
}
[effect_barracks_iii]
-name = "Land_Veteran"
+name = "Veteran_Build"
value = 1
reqs =
{ "type", "name", "range"
"Building", "Barracks III", "City"
+ "UnitClass", "Land", "Local"
}
+nreqs =
+ { "type", "name", "range"
+ "UnitFlag", "Diplomat", "Local"
+ }
[effect_barracks_iii_1]
-name = "Land_Regen"
-value = 1
+name = "HP_Regen"
+value = 100
reqs =
{ "type", "name", "range"
"Building", "Barracks III", "City"
+ "UnitClass", "Land", "Local"
}
[effect_cathedral]
@@ -540,17 +599,31 @@
}
[effect_city_walls]
-name = "Land_Defend"
+name = "Defend_Bonus"
value = 200
reqs =
{ "type", "name", "range"
"Building", "City Walls", "City"
+ "UnitClass", "Land", "Local"
}
nreqs =
{ "type", "name", "range"
"Building", "Great Wall", "Player"
}
+[effect_city_walls]
+name = "Defend_Bonus"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "City Walls", "City"
+ "UnitClass", "Helicopter", "Local"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
[effect_city_walls_1]
name = "Unit_No_Lose_Pop"
value = 1
@@ -560,11 +633,12 @@
}
[effect_coastal_defense]
-name = "Sea_Defend"
+name = "Defend_Bonus"
value = 100
reqs =
{ "type", "name", "range"
"Building", "Coastal Defense", "City"
+ "UnitClass", "Sea", "Local"
}
[effect_colosseum]
@@ -892,19 +966,21 @@
}
[effect_port_facility]
-name = "Sea_Veteran"
+name = "Veteran_Build"
value = 1
reqs =
{ "type", "name", "range"
"Building", "Port Facility", "City"
+ "UnitClass", "Sea", "Local"
}
[effect_port_facility_1]
-name = "Sea_Regen"
-value = 1
+name = "HP_Regen"
+value = 100
reqs =
{ "type", "name", "range"
"Building", "Port Facility", "City"
+ "UnitClass", "Sea", "Local"
}
[effect_power_plant]
@@ -968,11 +1044,12 @@
}
[effect_sam_battery]
-name = "Air_Defend"
+name = "Defend_Bonus"
value = 100
reqs =
{ "type", "name", "range"
"Building", "SAM Battery", "City"
+ "UnitClass", "Air", "Local"
}
[effect_sdi_defense]
@@ -984,11 +1061,12 @@
}
[effect_sdi_defense_1]
-name = "Missile_Defend"
+name = "Defend_Bonus"
value = 100
reqs =
{ "type", "name", "range"
"Building", "SDI Defense", "City"
+ "UnitClass", "Missile", "Local"
}
[effect_sewer_system]
@@ -1190,13 +1268,23 @@
}
[effect_great_wall]
-name = "Land_Defend"
+name = "Defend_Bonus"
value = 200
reqs =
{ "type", "name", "range"
"Building", "Great Wall", "Player"
+ "UnitClass", "Land", "Local"
}
+[effect_great_wall]
+name = "Defend_Bonus"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ "UnitClass", "Helicopter", "Local"
+ }
+
[effect_great_wall_1]
name = "Unit_No_Lose_Pop"
value = 1
@@ -1303,11 +1391,12 @@
}
[effect_lighthouse]
-name = "Sea_Move"
+name = "Move_Bonus"
value = 1
reqs =
{ "type", "name", "range"
"Building", "Lighthouse", "Player"
+ "UnitClass", "Sea", "Local"
}
[effect_lighthouse_1]
@@ -1319,19 +1408,21 @@
}
[effect_lighthouse_2]
-name = "Sea_Veteran"
+name = "Veteran_Build"
value = 1
reqs =
{ "type", "name", "range"
"Building", "Lighthouse", "Player"
+ "UnitClass", "Sea", "Local"
}
[effect_magellans_expedition]
-name = "Sea_Move"
+name = "Move_Bonus"
value = 2
reqs =
{ "type", "name", "range"
"Building", "Magellan's Expedition", "Player"
+ "UnitClass", "Sea", "Local"
}
[effect_manhattan_project]
@@ -1428,20 +1519,26 @@
}
[effect_sun_tzus_war_academy]
-name = "Land_Veteran"
+name = "Veteran_Build"
value = 1
reqs =
{ "type", "name", "range"
"Building", "Sun Tzu's War Academy", "Player"
+ "UnitClass", "Land", "Local"
}
[effect_sun_tzus_war_academy_1]
-name = "Land_Vet_Combat"
+name = "Veteran_Combat"
value = 50
reqs =
{ "type", "name", "range"
"Building", "Sun Tzu's War Academy", "Player"
+ "UnitClass", "Land", "Local"
}
+nreqs =
+ { "type", "name", "range"
+ "UnitFlag", "Diplomat", "Local"
+ }
[effect_united_nations]
name = "Unit_Recover"
Index: data/history/effects.ruleset
===================================================================
--- data/history/effects.ruleset (revision 11124)
+++ data/history/effects.ruleset (working copy)
@@ -206,17 +206,31 @@
}
[effect_city_walls]
-name = "Land_Defend"
+name = "Defend_Bonus"
value = 200
reqs =
{ "type", "name", "range"
"Building", "City Walls", "City"
+ "UnitClass", "Land", "Local"
}
nreqs =
{ "type", "name", "range"
"Building", "Great Wall", "Player"
}
+[effect_city_walls]
+name = "Defend_Bonus"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "City Walls", "City"
+ "UnitClass", "Helicopter", "Local"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
[effect_city_walls_1]
name = "Unit_No_Lose_Pop"
value = 1
@@ -226,11 +240,12 @@
}
[effect_coastal_defense]
-name = "Sea_Defend"
+name = "Defend_Bonus"
value = 100
reqs =
{ "type", "name", "range"
"Building", "Coastal Defense", "City"
+ "UnitClass", "Sea", "Local"
}
[effect_colosseum]
@@ -597,11 +612,12 @@
}
[effect_sam_battery]
-name = "Air_Defend"
+name = "Defend_Bonus"
value = 100
reqs =
{ "type", "name", "range"
"Building", "SAM Battery", "City"
+ "UnitClass", "Air", "Local"
}
[effect_sdi_defense]
@@ -613,11 +629,12 @@
}
[effect_sdi_defense_1]
-name = "Missile_Defend"
+name = "Defend_Bonus"
value = 100
reqs =
{ "type", "name", "range"
"Building", "SDI Defense", "City"
+ "UnitClass", "Missile", "Local"
}
[effect_sewer_system]
@@ -787,13 +804,23 @@
}
[effect_great_wall]
-name = "Land_Defend"
+name = "Defend_Bonus"
value = 200
reqs =
{ "type", "name", "range"
"Building", "Great Wall", "Player"
+ "UnitClass", "Land", "Local"
}
+[effect_great_wall]
+name = "Defend_Bonus"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ "UnitClass", "Helicopter", "Local"
+ }
+
[effect_great_wall_1]
name = "Unit_No_Lose_Pop"
value = 1
Index: common/combat.c
===================================================================
--- common/combat.c (revision 11124)
+++ common/combat.c (working copy)
@@ -258,8 +258,8 @@
}
if (unit_flag(attacker, F_BADWALLATTACKER)
- && pcity
- && get_city_bonus(pcity, EFT_LAND_DEFEND) > 0) {
+ && get_unittype_bonus(defender->owner, defender->tile, attacker->type,
+ EFT_DEFEND_BONUS) > 0) {
*att_fp = 1;
}
@@ -431,6 +431,7 @@
**************************************************************************/
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)
{
@@ -451,26 +452,13 @@
(is_air_unittype(att_type) || is_heli_unittype(att_type))) {
defensepower *= 5;
}
-
- if (is_air_unittype(att_type) && pcity) {
- if ((mod = get_city_bonus(pcity, EFT_AIR_DEFEND)) > 0) {
- defensepower = defensepower * (100 + mod) / 100;
- }
- if ((mod = get_city_bonus(pcity, EFT_MISSILE_DEFEND)) > 0
- && unit_type_flag(att_type, F_MISSILE)) {
- defensepower = defensepower * (100 + mod) / 100;
- }
- } else if (is_sailing_unittype(att_type) && pcity) {
- if ((mod = get_city_bonus(pcity, EFT_SEA_DEFEND)) > 0) {
- defensepower = defensepower * (100 + mod) / 100;
- }
+
+ if (!unit_type_flag(att_type, F_IGWALL)) {
+ /* This applies even if pcity is NULL. */
+ mod = 100 + get_unittype_bonus(def_player, ptile,
+ att_type, EFT_DEFEND_BONUS);
+ defensepower = MAX(0, defensepower * mod / 100);
}
- if (!unit_type_flag(att_type, F_IGWALL)
- && (is_ground_unittype(att_type) || is_heli_unittype(att_type))
- && pcity
- && (mod = get_city_bonus(pcity, EFT_LAND_DEFEND)) > 0) {
- defensepower = defensepower * (100 + mod) / 100;
- }
if (unit_type_flag(att_type, F_FIGHTER) && is_heli_unittype(def_type)) {
defensepower /= 2;
@@ -495,6 +483,7 @@
**************************************************************************/
int get_virtual_defense_power(const struct unit_type *att_type,
const struct unit_type *def_type,
+ const struct player *def_player,
const struct tile *ptile,
bool fortified, int veteran)
{
@@ -514,7 +503,8 @@
defensepower *= db;
defensepower *= def_type->veteran[veteran].power_fact;
- return defense_multiplication(att_type, def_type, ptile, defensepower,
+ return defense_multiplication(att_type, def_type, def_player,
+ ptile, defensepower,
fortified);
}
@@ -527,6 +517,7 @@
const struct unit *defender)
{
return defense_multiplication(attacker->type, defender->type,
+ defender->owner,
defender->tile,
get_defense_power(defender),
defender->activity == ACTIVITY_FORTIFIED);
Index: common/city.c
===================================================================
--- common/city.c (revision 11124)
+++ common/city.c (working copy)
@@ -971,7 +971,7 @@
**************************************************************************/
bool city_got_citywalls(const struct city *pcity)
{
- return (get_city_bonus(pcity, EFT_LAND_DEFEND) > 0);
+ return (get_city_bonus(pcity, EFT_DEFEND_BONUS) > 0);
}
/**************************************************************************
Index: common/combat.h
===================================================================
--- common/combat.h (revision 11124)
+++ common/combat.h (working copy)
@@ -56,6 +56,7 @@
const struct unit *defender);
int get_virtual_defense_power(const struct unit_type *attacker,
const struct unit_type *defender,
+ const struct player *defending_player,
const struct tile *ptile,
bool fortified, int veteran);
int get_total_attack_power(const struct unit *attacker,
Index: common/movement.c
===================================================================
--- common/movement.c (revision 11124)
+++ common/movement.c (working copy)
@@ -53,13 +53,12 @@
move_rate = (move_rate * punit->hp) / unit_type(punit)->hp;
}
+ /* Add on effects bonus (Magellan's Expedition, Lighthouse,
+ * Nuclear Power). */
+ move_rate += (get_unit_bonus(punit, EFT_MOVE_BONUS) * SINGLE_MOVE);
+
/* TODO: These effects should not be hardcoded to unit class enumeration */
if (pclass->id == UCL_SEA) {
- /* Add on effects bonus (Magellan's Expedition, Lighthouse,
- * Nuclear Power). */
- move_rate += (get_unit_bonus(punit, EFT_SEA_MOVE)
- * SINGLE_MOVE);
-
/* Don't let the move_rate be less than 2 unless the base_move_rate is
* also less than 2. */
if (move_rate < 2 * SINGLE_MOVE) {
Index: common/effects.c
===================================================================
--- common/effects.c (revision 11124)
+++ common/effects.c (working copy)
@@ -80,26 +80,17 @@
"SS_Component",
"SS_Module",
"Spy_Resistant",
- "Sea_Move",
+ "Move_Bonus",
"Unit_No_Lose_Pop",
"Unit_Recover",
"Upgrade_Unit",
"Upkeep_Free",
"No_Unhappy",
- "Land_Veteran",
- "Sea_Veteran",
- "Air_Veteran",
- "Land_Vet_Combat",
- /* TODO: "Sea_Vet_Combat", */
- /* TODO: "Air_Vet_Combat", */
- "Land_Regen",
- "Sea_Regen",
- "Air_Regen",
+ "Veteran_Build",
+ "Veteran_Combat",
+ "HP_Regen",
"City_Vision_Radius_Sq",
- "Land_Defend",
- "Sea_Defend",
- "Air_Defend",
- "Missile_Defend",
+ "Defend_Bonus",
"No_Incite",
"Gain_AI_Love",
"Slow_Down_Timeline",
@@ -111,7 +102,6 @@
"Martial_Law_Max",
"Rapture_Grow",
"Unbribable_Units",
- "Veteran_Diplomats",
"Revolution_When_Unhappy",
"Has_Senate",
"Inspire_Partisans",
@@ -830,14 +820,35 @@
}
/**************************************************************************
+ Returns the effect bonus that applies at a tile for a given unittype.
+
+ For instance with EFT_DEFEND_BONUS the attacker's unittype and the
+ defending tile should be passed in. Slightly counter-intuitive!
+ See doc/README.effects to see how the unittype applies for each effect
+ here.
+**************************************************************************/
+int get_unittype_bonus(const struct player *pplayer,
+ const struct tile *ptile,
+ const struct unit_type *punittype,
+ enum effect_type effect_type)
+{
+ assert(pplayer != NULL && ptile != NULL && punittype != NULL);
+ return get_target_bonus_effects(NULL,
+ pplayer, ptile->city, NULL, ptile,
+ punittype, NULL, NULL, effect_type);
+}
+
+/**************************************************************************
Returns the effect bonus at a building.
**************************************************************************/
int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
{
assert(punit != NULL);
return get_target_bonus_effects(NULL,
- unit_owner(punit), NULL, NULL,
- NULL, punit->type, NULL, NULL,
+ unit_owner(punit),
+ punit->tile ? punit->tile->city : NULL,
+ NULL, punit->tile,
+ punit->type, NULL, NULL,
effect_type);
}
Index: common/effects.h
===================================================================
--- common/effects.h (revision 11124)
+++ common/effects.h (working copy)
@@ -68,26 +68,17 @@
EFT_SS_COMPONENT,
EFT_SS_MODULE,
EFT_SPY_RESISTANT,
- EFT_SEA_MOVE,
+ EFT_MOVE_BONUS,
EFT_UNIT_NO_LOSE_POP,
EFT_UNIT_RECOVER,
EFT_UPGRADE_UNIT,
EFT_UPKEEP_FREE,
EFT_NO_UNHAPPY,
- EFT_LAND_VETERAN,
- EFT_SEA_VETERAN,
- EFT_AIR_VETERAN,
- EFT_LAND_VET_COMBAT,
- /* TODO: EFT_SEA_VET_COMBAT, */
- /* TODO: EFT_AIR_VET_COMBAT, */
- EFT_LAND_REGEN,
- EFT_SEA_REGEN,
- EFT_AIR_REGEN,
+ EFT_VETERAN_BUILD,
+ EFT_VETERAN_COMBAT,
+ EFT_HP_REGEN,
EFT_CITY_VISION_RADIUS_SQ,
- EFT_LAND_DEFEND,
- EFT_SEA_DEFEND,
- EFT_AIR_DEFEND,
- EFT_MISSILE_DEFEND,
+ EFT_DEFEND_BONUS,
EFT_NO_INCITE,
EFT_GAIN_AI_LOVE,
EFT_SLOW_DOWN_TIMELINE,
@@ -99,7 +90,6 @@
EFT_MARTIAL_LAW_MAX,
EFT_RAPTURE_GROW,
EFT_UNBRIBABLE_UNITS,
- EFT_VETERAN_DIPLOMATS,
EFT_REVOLUTION_WHEN_UNHAPPY,
EFT_HAS_SENATE,
EFT_INSPIRE_PARTISANS,
@@ -183,6 +173,10 @@
enum effect_type effect_type);
int get_building_bonus(const struct city *pcity, Impr_type_id building,
enum effect_type effect_type);
+int get_unittype_bonus(const struct player *pplayer,
+ const struct tile *ptile, /* pcity is implied */
+ const struct unit_type *punittype,
+ enum effect_type effect_type);
int get_unit_bonus(const struct unit *punit, enum effect_type effect_type);
/* miscellaneous auxiliary effects functions */
Index: ai/aiunit.h
===================================================================
--- ai/aiunit.h (revision 11124)
+++ ai/aiunit.h (working copy)
@@ -79,6 +79,7 @@
int unit_def_rating_basic_sq(struct unit *punit);
int unittype_def_rating_sq(const struct unit_type *att_type,
const struct unit_type *def_type,
+ const struct player *def_player,
struct tile *ptile, bool fortified, int veteran);
int kill_desire(int benefit, int attack, int loss, int vuln, int attack_count);
Index: ai/advdiplomacy.c
===================================================================
--- ai/advdiplomacy.c (revision 11124)
+++ ai/advdiplomacy.c (working copy)
@@ -652,8 +652,7 @@
want += pcity->size * 20;
want += pcity->surplus[O_SHIELD] * 8;
want += pcity->surplus[O_TRADE] * 6;
- fear += get_city_bonus(pcity, EFT_LAND_DEFEND);
- fear += get_city_bonus(pcity, EFT_SEA_DEFEND);
+ fear += get_city_bonus(pcity, EFT_DEFEND_BONUS);
built_impr_iterate(pcity, id) {
want += impr_build_shield_cost(id);
if (is_great_wonder(id)) {
Index: ai/aicity.c
===================================================================
--- ai/aicity.c (revision 11124)
+++ ai/aicity.c (working copy)
@@ -543,33 +543,29 @@
case EFT_SPY_RESISTANT:
/* Uhm, problem: City Wall has -50% here!! */
break;
- case EFT_SEA_MOVE:
- v += ai->stats.units.sea * 8 * amount;
+ case EFT_MOVE_BONUS:
+ /* FIXME: check other reqs (e.g., unitclass) */
+ v += (8 * v * amount + ai->stats.units.land
+ + ai->stats.units.sea + ai->stats.units.air);
break;
case EFT_UNIT_NO_LOSE_POP:
v += unit_list_size(ptile->units) * 2;
break;
- case EFT_LAND_REGEN:
- v += 5 * c + ai->stats.units.land * 3;
+ case EFT_HP_REGEN:
+ /* FIXME: check other reqs (e.g., unitclass) */
+ v += (5 * c + ai->stats.units.land
+ + ai->stats.units.sea + ai->stats.units.air);
break;
- case EFT_SEA_REGEN:
- v += 5 * c + ai->stats.units.sea * 3;
+ case EFT_VETERAN_COMBAT:
+ /* FIXME: check other reqs (e.g., unitclass) */
+ v += (2 * c + ai->stats.units.land + ai->stats.units.sea
+ + ai->stats.units.air);
break;
- case EFT_AIR_REGEN:
- v += 5 * c + ai->stats.units.air * 3;
+ case EFT_VETERAN_BUILD:
+ /* FIXME: check other reqs (e.g., unitclass, unitflag) */
+ v += (3 * c + ai->stats.units.land + ai->stats.units.sea
+ + ai->stats.units.air);
break;
- case EFT_LAND_VET_COMBAT:
- v += 2 * c + ai->stats.units.land * 2;
- break;
- case EFT_LAND_VETERAN:
- v += 3 * c + ai->stats.units.land;
- break;
- case EFT_SEA_VETERAN:
- v += 5 * c + ai->stats.units.sea;
- break;
- case EFT_AIR_VETERAN:
- v += 5 * c + ai->stats.units.air;
- break;
case EFT_UPGRADE_UNIT:
v += ai->stats.units.upgradeable;
if (amount == 1) {
@@ -580,7 +576,7 @@
v *= 4;
}
break;
- case EFT_SEA_DEFEND:
+ case EFT_DEFEND_BONUS:
if (ai_handicap(pplayer, H_DEFENSIVE)) {
v += amount / 10; /* make AI slow */
}
@@ -598,34 +594,16 @@
} adjc_iterate_end;
}
v += (amount/20 + ai->threats.invasions - 1) * c; /* for wonder */
- if (capital && ai->threats.invasions) {
- v += amount; /* defend capital! */
- }
- break;
- case EFT_AIR_DEFEND:
- if (ai_handicap(pplayer, H_DEFENSIVE)) {
- v += amount / 15; /* make AI slow */
- }
- v += (ai->threats.air && ai->threats.continent[ptile->continent])
- ? amount/10 * 5 + amount/10 * c : c;
- break;
- case EFT_MISSILE_DEFEND:
- if (ai->threats.missile
- && (ai->threats.continent[ptile->continent] || capital)) {
- v += amount/10 * 5 + (amount/10 - 1) * c;
- }
- break;
- case EFT_LAND_DEFEND:
- if (ai_handicap(pplayer, H_DEFENSIVE)) {
- v += amount / 10; /* make AI slow */
- }
if (ai->threats.continent[ptile->continent]
|| capital
|| (ai->threats.invasions
- && is_water_adjacent_to_tile(pcity->tile))) {
- v += amount / (!ai->threats.igwall ? (15 - capital * 5) : 15);
+ && is_water_adjacent_to_tile(pcity->tile))) {
+ if (ai->threats.continent[ptile->continent]) {
+ v += amount;
+ } else {
+ v += amount / (!ai->threats.igwall ? (15 - capital * 5) : 15);
+ }
}
- v += (1 + ai->threats.invasions + !ai->threats.igwall) * c;
break;
case EFT_NO_INCITE:
if (get_city_bonus(pcity, EFT_NO_INCITE) <= 0) {
@@ -655,7 +633,6 @@
case EFT_MARTIAL_LAW_MAX:
case EFT_RAPTURE_GROW:
case EFT_UNBRIBABLE_UNITS:
- case EFT_VETERAN_DIPLOMATS:
case EFT_REVOLUTION_WHEN_UNHAPPY:
case EFT_HAS_SENATE:
case EFT_INSPIRE_PARTISANS:
@@ -1069,7 +1046,7 @@
{
impr_type_iterate(id) {
if (can_city_sell_building(pcity, id)
- && !building_has_effect(id, EFT_LAND_DEFEND)) {
+ && !building_has_effect(id, EFT_DEFEND_BONUS)) {
/* selling walls to buy defenders is counterproductive -- Syela */
really_handle_city_sell(pplayer, pcity, id);
break;
@@ -1363,7 +1340,7 @@
built_impr_iterate(pcity, i) {
if(can_city_sell_building(pcity, i)
- && !building_has_effect(i, EFT_LAND_DEFEND)
+ && !building_has_effect(i, EFT_DEFEND_BONUS)
/* selling city walls is really, really dumb -- Syela */
&& (is_building_replaced(pcity, i)
|| building_unwanted(city_owner(pcity), i))) {
Index: ai/aihand.c
===================================================================
--- ai/aihand.c (revision 11124)
+++ ai/aihand.c (working copy)
@@ -313,7 +313,7 @@
/* Bonuses for non-economic abilities. We increase val by
* a very small amount here to choose govt in cases where
* we have no cities yet. */
- bonus += get_player_bonus(pplayer, EFT_VETERAN_DIPLOMATS) ? 3 : 0;
+ bonus += get_player_bonus(pplayer, EFT_VETERAN_BUILD) ? 3 : 0;
bonus -= get_player_bonus(pplayer, EFT_REVOLUTION_WHEN_UNHAPPY) ? 3 : 0;
bonus += get_player_bonus(pplayer, EFT_NO_INCITE) ? 4 : 0;
bonus += get_player_bonus(pplayer, EFT_UNBRIBABLE_UNITS) ? 2 : 0;
Index: ai/advmilitary.c
===================================================================
--- ai/advmilitary.c (revision 11124)
+++ ai/advmilitary.c (working copy)
@@ -61,6 +61,7 @@
if (can_build_unit(pcity, punittype)
&& (move_type == LAND_MOVING || move_type == SEA_MOVING)) {
const int defense = get_virtual_defense_power(v, punittype,
+ pcity->owner,
pcity->tile,
FALSE, FALSE);
@@ -326,6 +327,7 @@
{
unsigned int danger;
bool sailing;
+ int mod;
if (unit_flag(punit, F_NO_LAND_ATTACK)) return 0;
@@ -335,12 +337,9 @@
}
danger = unit_att_rating(punit);
- if (sailing && get_city_bonus(pcity, EFT_SEA_DEFEND) > 0) {
- danger /= 2;
- }
- if (is_air_unit(punit) && get_city_bonus(pcity, EFT_AIR_DEFEND) > 0) {
- danger /= 2;
- }
+ mod = 100 + get_unittype_bonus(pcity->owner, pcity->tile,
+ punit->type, EFT_DEFEND_BONUS);
+ danger = danger * 100 / MAX(mod, 1);
return danger;
}
@@ -453,7 +452,7 @@
static unsigned int assess_danger(struct city *pcity)
{
int i;
- int danger[5], defender[4];
+ int danger[5], defender;
struct player *pplayer = city_owner(pcity);
bool pikemen = FALSE;
unsigned int urgency = 0;
@@ -572,30 +571,12 @@
/* HACK: This needs changing if multiple improvements provide
* this effect. */
- defender[0] = ai_find_source_building(pplayer, EFT_LAND_DEFEND);
- defender[1] = ai_find_source_building(pplayer, EFT_SEA_DEFEND);
- defender[2] = ai_find_source_building(pplayer, EFT_AIR_DEFEND);
- defender[3] = ai_find_source_building(pplayer, EFT_MISSILE_DEFEND);
+ defender = ai_find_source_building(pplayer, EFT_DEFEND_BONUS);
- if (defender[0] != B_LAST) {
- ai_reevaluate_building(pcity, &pcity->ai.building_want[defender[0]],
- urgency, danger[1], assess_defense(pcity));
+ if (defender != B_LAST) {
+ ai_reevaluate_building(pcity, &pcity->ai.building_want[defender],
+ urgency, danger[1], assess_defense_igwall(pcity));
}
- if (defender[1] != B_LAST) {
- ai_reevaluate_building(pcity, &pcity->ai.building_want[defender[1]],
- urgency, danger[2],
- assess_defense_igwall(pcity));
- }
- if (defender[2] != B_LAST) {
- ai_reevaluate_building(pcity, &pcity->ai.building_want[defender[2]],
- urgency, danger[3],
- assess_defense_igwall(pcity));
- }
- if (defender[3] != B_LAST) {
- ai_reevaluate_building(pcity, &pcity->ai.building_want[defender[3]],
- urgency, danger[4],
- assess_defense_igwall(pcity));
- }
pcity->ai.danger = danger[0];
pcity->ai.urgency = urgency;
@@ -805,6 +786,7 @@
static void process_attacker_want(struct city *pcity,
int value,
struct unit_type *victim_unit_type,
+ struct player *victim_player,
int veteran, struct tile *ptile,
struct ai_choice *best_choice,
struct unit *boat,
@@ -852,9 +834,9 @@
punittype->obsoleted_by))
&& punittype->attack_strength > 0 /* or we'll get SIGFPE */
&& move_type == orig_move_type) {
- /* TODO: Case for Airport. -- Raahul */
- int will_be_veteran = (move_type == LAND_MOVING
- || ai_find_source_building(pplayer, EFT_SEA_VETERAN) != B_LAST);
+ /* TODO: check for the right _type_ of building. */
+ int will_be_veteran
+ = (ai_find_source_building(pplayer, EFT_VETERAN_BUILD) != B_LAST);
/* Cost (shield equivalent) of gaining these techs. */
/* FIXME? Katvrr advises that this should be weighted more heavily in big
* danger. */
@@ -902,6 +884,7 @@
/* Estimate strength of the enemy. */
vuln = unittype_def_rating_sq(punittype, victim_unit_type,
+ victim_player,
ptile, FALSE, veteran);
/* Not bothering to s/!vuln/!pdef/ here for the time being. -- Syela
@@ -1004,21 +987,20 @@
int attack;
/* Benefit from fighting the target */
int benefit;
- /* Enemy defender type */
+ /* Defender of the target city/tile */
+ struct unit *pdef;
struct unit_type *def_type;
+ struct player *def_owner;
+ int def_vet; /* Is the defender veteran? */
/* Target coordinates */
struct tile *ptile;
/* Our transport */
struct unit *ferryboat = NULL;
/* Our target */
struct city *acity;
- /* Defender of the target city/tile */
- struct unit *pdef;
/* Type of the boat (real or a future one) */
struct unit_type *boattype = NULL;
bool go_by_boat;
- /* Is the defender veteran? */
- int def_vet;
struct ai_choice best_choice;
init_choice(&best_choice);
@@ -1099,9 +1081,10 @@
go_by_boat, ferryboat, boattype);
def_type = ai_choose_defender_versus(acity, myunit->type);
+ def_owner = acity->owner;
if (move_time > 1) {
def_vet = do_make_unit_veteran(acity, def_type);
- vuln = unittype_def_rating_sq(myunit->type, def_type,
+ vuln = unittype_def_rating_sq(myunit->type, def_type, acity->owner,
ptile, FALSE, def_vet);
benefit = unit_build_shield_cost(def_type);
} else {
@@ -1112,13 +1095,14 @@
pdef = get_defender(myunit, ptile);
if (pdef) {
- int m = unittype_def_rating_sq(myunit->type, pdef->type,
+ int m = unittype_def_rating_sq(myunit->type, pdef->type, acity->owner,
ptile, FALSE, pdef->veteran);
if (vuln < m) {
vuln = m;
benefit = unit_build_shield_cost(pdef->type);
def_vet = pdef->veteran;
def_type = pdef->type;
+ def_owner = pdef->owner;
}
}
if (COULD_OCCUPY(myunit) || TEST_BIT(acity->ai.invasion, 0)) {
@@ -1140,17 +1124,20 @@
def_type = pdef->type;
def_vet = pdef->veteran;
+ def_owner = pdef->owner;
/* end dealing with units */
}
if (!go_by_boat) {
- process_attacker_want(pcity, benefit, def_type, def_vet, ptile,
+ process_attacker_want(pcity, benefit, def_type, def_owner,
+ def_vet, ptile,
&best_choice, NULL, NULL);
} else {
/* Attract a boat to our city or retain the one that's already here */
assert(is_ground_unit(myunit));
best_choice.need_boat = TRUE;
- process_attacker_want(pcity, benefit, def_type, def_vet, ptile,
+ process_attacker_want(pcity, benefit, def_type, def_owner,
+ def_vet, ptile,
&best_choice, ferryboat, boattype);
}
@@ -1230,31 +1217,11 @@
}
move_type = get_unit_type(choice->choice)->move_type;
- switch(move_type) {
- case LAND_MOVING:
- if ((id = ai_find_source_building(pplayer, EFT_LAND_VETERAN)) != B_LAST) {
- choice->choice = id;
- choice->type = CT_BUILDING;
- }
- break;
- case SEA_MOVING:
- if ((id = ai_find_source_building(pplayer, EFT_SEA_VETERAN)) != B_LAST) {
- choice->choice = id;
- choice->type = CT_BUILDING;
- }
- break;
- case HELI_MOVING:
- case AIR_MOVING:
- if ((id = ai_find_source_building(pplayer, EFT_AIR_VETERAN)) != B_LAST
- && pcity->surplus[O_SHIELD] > impr_build_shield_cost(id) / 10) {
- /* Only build this if we have really high production */
- choice->choice = id;
- choice->type = CT_BUILDING;
- }
- break;
- default:
- freelog(LOG_ERROR, "Unknown move_type in adjust_ai_unit_choice");
- assert(FALSE);
+
+ /* TODO: separate checks based on other requirements (e.g., unit class) */
+ if ((id = ai_find_source_building(pplayer, EFT_VETERAN_BUILD)) != B_LAST) {
+ choice->choice = id;
+ choice->type = CT_BUILDING;
}
}
@@ -1290,7 +1257,7 @@
/* Otherwise no need to defend yet */
if (pcity->ai.danger != 0) {
int num_defenders = unit_list_size(ptile->units);
- int land_id, sea_id, air_id, danger;
+ int wall_id, danger;
/* First determine the danger. It is measured in percents of our
* defensive strength, capped at 200 + urgency */
@@ -1322,61 +1289,32 @@
/* HACK: This needs changing if multiple improvements provide
* this effect. */
- land_id = ai_find_source_building(pplayer, EFT_LAND_DEFEND);
- sea_id = ai_find_source_building(pplayer, EFT_SEA_DEFEND);
- air_id = ai_find_source_building(pplayer, EFT_AIR_DEFEND);
+ wall_id = ai_find_source_building(pplayer, EFT_DEFEND_BONUS);
- if (land_id != B_LAST
- && pcity->ai.building_want[land_id] != 0 && our_def != 0
- && can_build_improvement(pcity, land_id)
+ if (wall_id != B_LAST
+ && pcity->ai.building_want[wall_id] != 0 && our_def != 0
+ && can_build_improvement(pcity, wall_id)
&& (danger < 101 || num_defenders > 1
|| (pcity->ai.grave_danger == 0
&& pplayer->economic.gold > (80 - pcity->shield_stock) * 2))
&& ai_fuzzy(pplayer, TRUE)) {
/* NB: great wall is under domestic */
- choice->choice = land_id;
+ choice->choice = wall_id;
/* building_want is hacked by assess_danger */
- choice->want = pcity->ai.building_want[land_id];
+ choice->want = pcity->ai.building_want[wall_id];
if (urgency == 0 && choice->want > 100) {
choice->want = 100;
}
choice->type = CT_BUILDING;
- CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d wants land defense building with %d",
+ CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d wants defense building with %d",
choice->want);
- } else if (sea_id != B_LAST
- && pcity->ai.building_want[sea_id] != 0 && our_def != 0
- && can_build_improvement(pcity, sea_id)
- && (danger < 101 || num_defenders > 1)
- && ai_fuzzy(pplayer, TRUE)) {
- choice->choice = sea_id;
- /* building_want is hacked by assess_danger */
- choice->want = pcity->ai.building_want[sea_id];
- if (urgency == 0 && choice->want > 100) {
- choice->want = 100;
- }
- choice->type = CT_BUILDING;
- CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d wants sea defense building with %d",
- choice->want);
- } else if (air_id != B_LAST
- && pcity->ai.building_want[air_id] != 0 && our_def != 0
- && can_build_improvement(pcity, air_id)
- && (danger < 101 || num_defenders > 1)
- && ai_fuzzy(pplayer, TRUE)) {
- choice->choice = air_id;
- /* building_want is hacked by assess_danger */
- choice->want = pcity->ai.building_want[air_id];
- if (urgency == 0 && choice->want > 100) {
- choice->want = 100;
- }
- choice->type = CT_BUILDING;
- CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d wants air defense building with %d",
- choice->want);
} else if (danger > 0 && num_defenders <= urgency) {
/* Consider building defensive units units */
process_defender_want(pplayer, pcity, danger, choice);
if (urgency == 0
&& get_unit_type(choice->choice)->defense_strength == 1) {
- if (get_city_bonus(pcity, EFT_LAND_REGEN) > 0) {
+ /* FIXME: check other reqs (unit class?) */
+ if (get_city_bonus(pcity, EFT_HP_REGEN) > 0) {
/* unlikely */
choice->want = MIN(49, danger);
} else {
Index: ai/aiunit.c
===================================================================
--- ai/aiunit.c (revision 11124)
+++ ai/aiunit.c (working copy)
@@ -395,9 +395,10 @@
**************************************************************************/
int unittype_def_rating_sq(const struct unit_type *att_type,
const struct unit_type *def_type,
+ const struct player *def_player,
struct tile *ptile, bool fortified, int veteran)
{
- int v = get_virtual_defense_power(att_type, def_type, ptile,
+ int v = get_virtual_defense_power(att_type, def_type, def_player, ptile,
fortified, veteran)
* def_type->hp * def_type->firepower / POWER_DIVIDER;
@@ -497,12 +498,14 @@
continue;
if (!can_unit_attack_all_at_tile(aunit, pdef->tile))
continue;
- d = get_virtual_defense_power(aunit->type, pdef->type, pdef->tile,
+ d = get_virtual_defense_power(aunit->type, pdef->type, pdef->owner,
+ pdef->tile,
FALSE, 0);
if (d == 0)
return TRUE; /* Thanks, Markus -- Syela */
cur = unit_att_rating_now(aunit) *
- get_virtual_defense_power(punit->type, pdef->type, pdef->tile,
+ get_virtual_defense_power(punit->type, pdef->type,
+ pdef->owner, pdef->tile,
FALSE, 0) / d;
if (cur > val && ai_fuzzy(unit_owner(punit), TRUE))
return FALSE;
@@ -1392,7 +1395,7 @@
struct unit_type *def_type
= ai_choose_defender_versus(acity, punit->type);
int v = unittype_def_rating_sq(punit->type, def_type,
- acity->tile, FALSE,
+ acity->owner, acity->tile, FALSE,
do_make_unit_veteran(acity, def_type));
if (v > vuln) {
/* They can build a better defender! */
@@ -1600,15 +1603,14 @@
city_list_iterate(aplayer->cities, pcity) {
if (ground) {
cur = WARMAP_COST(pcity->tile);
- if (get_city_bonus(pcity, EFT_LAND_REGEN) > 0) {
- cur /= 3;
- }
} else {
cur = WARMAP_SEACOST(pcity->tile);
- if (get_city_bonus(pcity, EFT_SEA_REGEN) > 0) {
- cur /= 3;
- }
}
+ /* Note the "player" here is the unit owner NOT the city owner. */
+ if (get_unittype_bonus(punit->owner, pcity->tile, punit->type,
+ EFT_HP_REGEN) > 0) {
+ cur /= 3;
+ }
if (cur < best) {
best = cur;
acity = pcity;
- [Freeciv-Dev] (PR#14314) effects and unitclass cleanup,
Jason Short <=
|
|