? diff ? a ? all.diff ? test.s ? auto.rc ? test.c ? freeciv ? oilmine.patch Index: ai/advmilitary.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/advmilitary.c,v retrieving revision 1.91 diff -u -r1.91 advmilitary.c --- ai/advmilitary.c 2002/02/25 19:05:13 1.91 +++ ai/advmilitary.c 2002/02/26 09:25:25 @@ -161,19 +161,14 @@ { int v; bool sailing; - struct unit_type *ptype; if (unit_flag(punit, F_NO_LAND_ATTACK)) return(0); sailing = is_sailing_unit(punit); if (sailing && !is_terrain_near_tile(pcity->x, pcity->y, T_OCEAN)) return(0); - ptype = unit_type(punit); -/* get_attack_power will be wrong if moves_left == 1 || == 2 */ - v = ptype->attack_strength * 10 * punit->hp * ptype->firepower; - if (punit->veteran) v += v/2; + v = unit_belligerence_basic(punit); if (sailing && city_got_building(pcity, B_COASTAL)) v /= 2; if (is_air_unit(punit) && city_got_building(pcity, B_SAM)) v /= 2; - v /= 30; /* rescaling factor to stop the overflow nonsense */ return(v); } @@ -571,10 +566,11 @@ l /= city_list_size(&pplayer->cities); /* Katvrr advises that with danger high, l should be weighted more heavily */ - a = unit_types[i].attack_strength * ((m == LAND_MOVING || - player_knows_improvement_tech(pplayer, B_PORT)) ? 15 : 10) * - unit_types[i].firepower * unit_types[i].hp; - a /= 30; /* scaling factor to prevent integer overflows */ + a = base_unit_belligerence_primitive(i, FALSE, SINGLE_MOVE, + unit_types[i].hp); + if (m == LAND_MOVING || player_knows_improvement_tech(pplayer, B_PORT)) { + a = (a * 3) / 2; + } if (acity) a += acity->ai.a; a *= a; /* b is unchanged */ @@ -701,9 +697,7 @@ v = myunit->type; vet = myunit->veteran; - a = unit_types[v].attack_strength * (vet ? 15 : 10) * - unit_types[v].firepower * myunit->hp; - a /= 30; /* scaling factor to prevent integer overflows */ + a = unit_belligerence_basic(myunit); if (acity) a += acity->ai.a; a *= a; Index: ai/aiunit.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v retrieving revision 1.180 diff -u -r1.180 aiunit.c --- ai/aiunit.c 2002/02/25 19:05:13 1.180 +++ ai/aiunit.c 2002/02/26 09:25:27 @@ -561,20 +561,23 @@ /************************************************************************** ... **************************************************************************/ +int base_unit_belligerence_primitive(Unit_Type_id type, bool veteran, + int moves_left, int hp) +{ + return (base_get_attack_power(type, veteran, moves_left) * hp * + get_unit_type(type)->firepower / POWER_DIVIDER); +} + static int unit_belligerence_primitive(struct unit *punit) { - int v; - v = get_attack_power(punit) * punit->hp * - unit_type(punit)->firepower / 30; - return(v); + return (base_unit_belligerence_primitive(punit->type, punit->veteran, + punit->moves_left, punit->hp)); } int unit_belligerence_basic(struct unit *punit) { - int v; - v = unit_type(punit)->attack_strength * (punit->veteran ? 15 : 10) * - punit->hp * unit_type(punit)->firepower / 30; - return(v); + return (base_unit_belligerence_primitive(punit->type, punit->veteran, + SINGLE_MOVE, punit->hp)); } int unit_belligerence(struct unit *punit) @@ -1039,7 +1042,7 @@ static int ai_military_gothere(struct player *pplayer, struct unit *punit, int dest_x, int dest_y) { - int id, x, y, boatid = 0, bx = 0, by = 0, j; + int id, x, y, boatid = 0, bx = 0, by = 0; struct unit *ferryboat; struct unit *def; struct city *dcity; @@ -1057,9 +1060,9 @@ d_val = stack_attack_value(dest_x, dest_y) * 30; if ((dcity = map_get_city(dest_x, dest_y))) { d_type = ai_choose_defender_versus(dcity, punit->type); - j = unit_types[d_type].hp * (do_make_unit_veteran(dcity, d_type) ? 15 : 10) * - unit_types[d_type].attack_strength; - d_val += j; + d_val += base_get_attack_power(d_type, + do_make_unit_veteran(dcity, d_type), + SINGLE_MOVE) * unit_types[d_type].hp; } d_val /= (unit_type(punit)->move_rate / SINGLE_MOVE); if (unit_flag(punit, F_IGTER)) d_val /= 1.5; Index: ai/aiunit.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.h,v retrieving revision 1.30 diff -u -r1.30 aiunit.h --- ai/aiunit.h 2002/02/25 19:05:14 1.30 +++ ai/aiunit.h 2002/02/26 09:25:27 @@ -14,7 +14,16 @@ #define FC__AIUNIT_H #include "unittype.h" +#include "combat.h" +/* + * To prevent integer overflows the product "power * hp * firepower" + * is divided by POWER_DIVIDER. + * + * The constant may be changed since it isn't externally visible used. + */ +#define POWER_DIVIDER (POWER_FACTOR * 3) + struct player; struct city; struct unit; @@ -33,6 +42,8 @@ int find_beachhead(struct unit *punit, int dest_x, int dest_y, int *x, int *y); int build_cost_balanced(Unit_Type_id type); +int base_unit_belligerence_primitive(Unit_Type_id type, bool veteran, + int moves_left, int hp); int unit_belligerence_basic(struct unit *punit); int unit_belligerence(struct unit *punit); int unit_vulnerability_basic(struct unit *punit, struct unit *pdef); Index: common/combat.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/combat.c,v retrieving revision 1.19 diff -u -r1.19 combat.c --- common/combat.c 2002/02/16 17:05:05 1.19 +++ common/combat.c 2002/02/26 09:25:33 @@ -236,20 +236,33 @@ } /************************************************************************** - returns the attack power, modified by moves left, and veteran status. + Convenience wrapper for base_get_attack_power. **************************************************************************/ int get_attack_power(struct unit *punit) { + return base_get_attack_power(punit->type, punit->veteran, + punit->moves_left); +} + +/************************************************************************** + Returns the attack power, modified by moves left, and veteran + status. Set moves_left to SINGLE_MOVE to disable the reduction of + power caused by tired units. +**************************************************************************/ +int base_get_attack_power(Unit_Type_id type, bool veteran, int moves_left) +{ int power; - power=unit_type(punit)->attack_strength*10; - if (punit->veteran) { - power *= 3; - power /= 2; + + power = get_unit_type(type)->attack_strength * POWER_FACTOR; + if (veteran) { + /* Veterans get +50% bonus. */ + power = (power * 3) / 2; + } + + if (!unit_type_flag(type, F_IGTIRED) && moves_left < SINGLE_MOVE) { + power = (power * moves_left) / SINGLE_MOVE; } - if (unit_flag(punit, F_IGTIRED)) return power; - if ( punit->moves_left < SINGLE_MOVE ) - return (power*punit->moves_left)/SINGLE_MOVE; - return power; + return power; } /************************************************************************** @@ -264,7 +277,7 @@ if (!punit || punit->type<0 || punit->type>=U_LAST || punit->type>=game.num_unit_types) abort(); - power=unit_type(punit)->defense_strength*10; + power = unit_type(punit)->defense_strength * POWER_FACTOR; if (punit->veteran) { power *= 3; power /= 2; Index: common/combat.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/combat.h,v retrieving revision 1.4 diff -u -r1.4 combat.h --- common/combat.h 2002/02/14 15:17:09 1.4 +++ common/combat.h 2002/02/26 09:25:33 @@ -15,6 +15,14 @@ #include "unittype.h" +/* + * attack_strength and defense_strength are multiplied by POWER_FACTOR + * to yield the base of attack_power and defense_power. + * + * The constant may be changed since it isn't externally visible used. + */ +#define POWER_FACTOR 10 + struct unit; struct player; @@ -34,6 +42,7 @@ struct city *sdi_defense_close(struct player *owner, int x, int y); int get_attack_power(struct unit *punit); +int base_get_attack_power(Unit_Type_id type, bool veteran, int moves_left); int get_defense_power(struct unit *punit); int get_total_defense_power(struct unit *attacker, struct unit *defender); int get_simple_defense_power(Unit_Type_id d_type, int x, int y);