diff -Nur -Xfreecivdiff.ignore freeciv-cvs/client/citydlg_common.c freeciv-patched/client/citydlg_common.c --- freeciv-cvs/client/citydlg_common.c 2003-07-10 11:53:34.000000000 +0100 +++ freeciv-patched/client/citydlg_common.c 2003-07-24 17:05:30.000000000 +0100 @@ -136,9 +136,9 @@ stock = pcity->shield_stock; if (pcity->is_building_unit) { - cost = get_unit_type(pcity->currently_building)->build_cost; + cost = unit_value_adjusted(pcity->currently_building, pcity); } else { - cost = get_improvement_type(pcity->currently_building)->build_cost; + cost = improvement_value_adjusted(pcity->currently_building, pcity); } if (!pcity->is_building_unit && pcity->currently_building == B_CAPITAL) { @@ -192,10 +192,10 @@ if (is_unit) { name = get_unit_name(id); - cost = get_unit_type(id)->build_cost; + cost = unit_value_adjusted(id, pcity); } else { name = get_impr_name_ex(pcity, id); - cost = get_improvement_type(id)->build_cost; + cost = improvement_value_adjusted(id, pcity); } if (turns < 999) { @@ -231,7 +231,7 @@ my_snprintf(buf[1], column_size, "%d/%d/%d", ptype->attack_strength, ptype->defense_strength, ptype->move_rate / 3); } - my_snprintf(buf[2], column_size, "%d", ptype->build_cost); + my_snprintf(buf[2], column_size, "%d", unit_value_adjusted(id, pcity)); } else { /* Total & turns left meaningless on capitalization */ if (id == B_CAPITAL) { @@ -260,7 +260,7 @@ } my_snprintf(buf[2], column_size, "%d", - get_improvement_type(id)->build_cost); + improvement_value_adjusted(id, pcity)); } } diff -Nur -Xfreecivdiff.ignore freeciv-cvs/client/cityrepdata.c freeciv-patched/client/cityrepdata.c --- freeciv-cvs/client/cityrepdata.c 2003-07-10 11:53:34.000000000 +0100 +++ freeciv-patched/client/cityrepdata.c 2003-07-24 17:05:30.000000000 +0100 @@ -374,10 +374,10 @@ if(pcity->is_building_unit) { name = get_unit_type(pcity->currently_building)->name; - cost = get_unit_type(pcity->currently_building)->build_cost; + cost = unit_value_adjusted(pcity->currently_building, pcity); } else { name = get_impr_name_ex(pcity, pcity->currently_building); - cost = get_improvement_type(pcity->currently_building)->build_cost; + cost = improvement_value_adjusted(pcity->currently_building, pcity); } my_snprintf(buf, sizeof(buf), "%s (%d/%d/%s/%d)%s", name, diff -Nur -Xfreecivdiff.ignore freeciv-cvs/client/climisc.c freeciv-patched/client/climisc.c --- freeciv-cvs/client/climisc.c 2003-07-24 17:04:38.000000000 +0100 +++ freeciv-patched/client/climisc.c 2003-07-24 17:05:30.000000000 +0100 @@ -624,7 +624,7 @@ if (is_unit) { name = get_unit_name(id); - cost = get_unit_type(id)->build_cost; + cost = unit_value_adjusted(id, pcity); pitem->section = unit_type_flag(id, F_NONMIL) ? 2 : 3; } else { name = get_impr_name_ex(pcity, id); @@ -632,7 +632,7 @@ cost = -1; pitem->section = 1; } else { - cost = get_improvement_type(id)->build_cost; + cost = improvement_value_adjusted(id, pcity); if (is_wonder(id)) { pitem->section = 4; } else { diff -Nur -Xfreecivdiff.ignore freeciv-cvs/client/gui-gtk/citydlg.c freeciv-patched/client/gui-gtk/citydlg.c --- freeciv-cvs/client/gui-gtk/citydlg.c 2003-07-24 17:01:32.000000000 +0100 +++ freeciv-patched/client/gui-gtk/citydlg.c 2003-07-24 17:05:30.000000000 +0100 @@ -1901,7 +1901,7 @@ get_city_dialog_production(pcity, buf, sizeof(buf)); if (pcity->is_building_unit) { - cost = get_unit_type(pcity->currently_building)->build_cost; + cost = unit_value_adjusted(pcity->currently_building, pcity); descr = get_unit_type(pcity->currently_building)->name; } else { if (pcity->currently_building == B_CAPITAL) { @@ -1909,7 +1909,7 @@ gtk_widget_set_sensitive(pdialog->overview.buy_command, FALSE); cost = 0; } else { - cost = get_improvement_type(pcity->currently_building)->build_cost;; + cost = improvement_value_adjusted(pcity->currently_building, pcity); } descr = get_impr_name_ex(pcity, pcity->currently_building); } diff -Nur -Xfreecivdiff.ignore freeciv-cvs/client/gui-gtk-2.0/citydlg.c freeciv-patched/client/gui-gtk-2.0/citydlg.c --- freeciv-cvs/client/gui-gtk-2.0/citydlg.c 2003-07-24 17:01:32.000000000 +0100 +++ freeciv-patched/client/gui-gtk-2.0/citydlg.c 2003-07-24 17:05:30.000000000 +0100 @@ -1505,7 +1505,7 @@ get_city_dialog_production(pcity, buf, sizeof(buf)); if (pcity->is_building_unit) { - cost = get_unit_type(pcity->currently_building)->build_cost; + cost = unit_value_adjusted(pcity->currently_building, pcity); descr = get_unit_type(pcity->currently_building)->name; } else { if (pcity->currently_building == B_CAPITAL) { @@ -1513,7 +1513,7 @@ gtk_widget_set_sensitive(pdialog->overview.buy_command, FALSE); cost = 0; } else { - cost = get_improvement_type(pcity->currently_building)->build_cost;; + cost = improvement_value_adjusted(pcity->currently_building, pcity); } descr = get_impr_name_ex(pcity, pcity->currently_building); } diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/city.c freeciv-patched/common/city.c --- freeciv-cvs/common/city.c 2003-07-24 17:05:30.000000000 +0100 +++ freeciv-patched/common/city.c 2003-07-24 17:05:30.000000000 +0100 @@ -283,12 +283,12 @@ int build=pcity->shield_stock; if (pcity->is_building_unit) { - total=unit_value(pcity->currently_building); + total = unit_value_adjusted(pcity->currently_building, pcity); if (build>=total) return 0; cost=(total-build)*2+(total-build)*(total-build)/20; } else { - total=improvement_value(pcity->currently_building); + total = improvement_value_adjusted(pcity->currently_building, pcity); if (build>=total) return 0; cost=(total-build)*2; @@ -1380,8 +1380,13 @@ int city_shield_surplus = pcity->shield_surplus; int city_shield_stock = include_shield_stock ? city_change_production_penalty(pcity, id, id_is_unit, FALSE) : 0; - int improvement_cost = id_is_unit ? - get_unit_type(id)->build_cost : get_improvement_type(id)->build_cost; + int improvement_cost; + + if (id_is_unit) { + improvement_cost = unit_value_adjusted(id, pcity); + } else { + improvement_cost = improvement_value_adjusted(id, pcity); + } if (include_shield_stock && (city_shield_stock >= improvement_cost)) { return 1; @@ -1855,6 +1860,10 @@ int attackpct[UCL_LAST + 1]; /* Attack multipliers */ int defensefppct[UCL_LAST + 1]; /* Firepower multipliers */ int attackfppct[UCL_LAST + 1]; + int impr_cost_adj; /* Cost modifiers */ + int unit_cost_adj[UCL_LAST + 1]; + int impr_cost_pct; /* Cost multipliers */ + int unit_cost_pct[UCL_LAST + 1]; int makecontentpct = 100, forcecontentpct = 100; int makecontentmil = 0, makecontentmilper = 0; int corruptadj = 0, corruptpct = 100; @@ -1874,8 +1883,10 @@ pplayer = city_owner(pcity); gov = get_gov_pcity(pcity); + impr_cost_pct = impr_cost_adj = 100; for (i = 0; i <= UCL_LAST; i++) { defensepct[i] = attackpct[i] = defensefppct[i] = attackfppct[i] = 100; + unit_cost_pct[i] = unit_cost_adj[i] = 100; } city_init_tile_mods(pcity); @@ -1930,6 +1941,19 @@ defensefppct[iter.imeff->aff_unit] = defensefppct[iter.imeff->aff_unit] * amount / 100; break; + case EFT_UNIT_COST: + unit_cost_adj[iter.imeff->aff_unit] += amount; + break; + case EFT_BUILDING_COST: + impr_cost_adj += amount; + break; + case EFT_UNIT_COST_PCT: + unit_cost_pct[iter.imeff->aff_unit] = + unit_cost_pct[iter.imeff->aff_unit] * amount / 100; + break; + case EFT_BUILDING_COST_PCT: + impr_cost_pct = impr_cost_pct * amount / 100; + break; case EFT_TAX_BONUS: update_bonus(tax_bonus, amount, &iter, TRUE); break; @@ -2056,11 +2080,13 @@ pcity->poppoladj = poppoladj; pcity->prodpoladj = prodpoladj; + pcity->impr_cost_pct = impr_cost_pct * impr_cost_adj / 100; for (i = 0; i <= UCL_LAST; i++) { pcity->defensepct[i] = defensepct[i]; pcity->attackpct[i] = attackpct[i]; pcity->attackfppct[i] = attackfppct[i]; pcity->defensefppct[i] = defensefppct[i]; + pcity->unit_cost_pct[i] = unit_cost_pct[i] * unit_cost_adj[i] / 100; } } diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/city.h freeciv-patched/common/city.h --- freeciv-cvs/common/city.h 2003-07-24 17:04:53.000000000 +0100 +++ freeciv-patched/common/city.h 2003-07-24 17:05:30.000000000 +0100 @@ -266,6 +266,10 @@ /* pollution modifiers from city improvements */ int poppoladj, prodpoladj, poladj; + /* cost modifiers */ + int impr_cost_pct; + int unit_cost_pct[UCL_LAST + 1]; + /* the totals */ int luxury_total, tax_total, science_total; diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/improvement.c freeciv-patched/common/improvement.c --- freeciv-cvs/common/improvement.c 2003-07-24 17:05:30.000000000 +0100 +++ freeciv-patched/common/improvement.c 2003-07-24 17:05:30.000000000 +0100 @@ -158,7 +158,11 @@ "Force_Happy", "Unit_Attack", "Unit_Attack_Firepower", - "Unit_Defend_Firepower" + "Unit_Defend_Firepower", + "Unit_Cost", + "Building_Cost", + "Unit_Cost_Pct", + "Building_Cost_Pct" }; /************************************************************************** @@ -342,6 +346,15 @@ } /************************************************************************** + Returns the effective value of the improvement, after applying any + cost modifiers. +**************************************************************************/ +int improvement_value_adjusted(Impr_Type_id id, struct city *pcity) +{ + return improvement_value(id) * pcity->impr_cost_pct / 100; +} + +/************************************************************************** ... **************************************************************************/ bool is_wonder(Impr_Type_id id) diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/improvement.h freeciv-patched/common/improvement.h --- freeciv-cvs/common/improvement.h 2003-07-24 17:05:30.000000000 +0100 +++ freeciv-patched/common/improvement.h 2003-07-24 17:05:30.000000000 +0100 @@ -183,6 +183,10 @@ EFT_UNIT_ATTACK, EFT_UNIT_ATTACK_FIREPOWER, EFT_UNIT_DEFEND_FIREPOWER, + EFT_UNIT_COST, + EFT_BUILDING_COST, + EFT_UNIT_COST_PCT, + EFT_BUILDING_COST_PCT, EFT_LAST /* keep this last */ }; @@ -402,6 +406,7 @@ struct impr_type *get_improvement_type(Impr_Type_id id); bool improvement_exists(Impr_Type_id id); int improvement_value(Impr_Type_id id); +int improvement_value_adjusted(Impr_Type_id id, struct city *pcity); bool is_wonder(Impr_Type_id id); const char *get_improvement_name(Impr_Type_id id); diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/unit.c freeciv-patched/common/unit.c --- freeciv-cvs/common/unit.c 2003-07-24 17:04:53.000000000 +0100 +++ freeciv-patched/common/unit.c 2003-07-24 17:05:31.000000000 +0100 @@ -201,15 +201,19 @@ **************************************************************************/ bool unit_can_help_build_wonder(struct unit *punit, struct city *pcity) { + int imp_value; + if (!is_tiles_adjacent(punit->x, punit->y, pcity->x, pcity->y) && !same_pos(punit->x, punit->y, pcity->x, pcity->y)) return FALSE; + imp_value = improvement_value_adjusted(pcity->currently_building, pcity); + return unit_flag(punit, F_HELP_WONDER) && punit->owner == pcity->owner && !pcity->is_building_unit && is_wonder(pcity->currently_building) - && pcity->shield_stock < improvement_value(pcity->currently_building); + && pcity->shield_stock < imp_value; } diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/unittype.c freeciv-patched/common/unittype.c --- freeciv-cvs/common/unittype.c 2003-07-24 17:04:53.000000000 +0100 +++ freeciv-patched/common/unittype.c 2003-07-24 17:05:31.000000000 +0100 @@ -223,6 +223,25 @@ } /************************************************************************** + Returns the effective value of the unit, after applying any + cost modifiers. +**************************************************************************/ +int unit_value_adjusted(Unit_Type_id id, struct city *pcity) +{ + int i, val; + struct unit_classes aff_unit; + + get_unittype_classes(id, &aff_unit); + val = unit_value(id); + for (i = 0; i <= UCL_LAST; ++i) { + if (is_unit_class_in_set(i, &aff_unit)) { + val = val * pcity->unit_cost_pct[i] / 100; + } + } + return val; +} + +/************************************************************************** ... **************************************************************************/ int unit_pop_value(Unit_Type_id id) diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/unittype.h freeciv-patched/common/unittype.h --- freeciv-cvs/common/unittype.h 2003-07-24 17:04:53.000000000 +0100 +++ freeciv-patched/common/unittype.h 2003-07-24 17:05:31.000000000 +0100 @@ -205,6 +205,7 @@ bool is_unit_class_in_set(Unit_Class_id id, struct unit_classes *classes); int unit_value(Unit_Type_id id); +int unit_value_adjusted(Unit_Type_id id, struct city *pcity); int unit_pop_value(Unit_Type_id id); const char *unit_name(Unit_Type_id id); diff -Nur -Xfreecivdiff.ignore freeciv-cvs/doc/README.effects freeciv-patched/doc/README.effects --- freeciv-cvs/doc/README.effects 2003-07-24 17:05:30.000000000 +0100 +++ freeciv-patched/doc/README.effects 2003-07-24 17:05:31.000000000 +0100 @@ -244,6 +244,22 @@ "Unit_Veteran" - all units of class .aff_unit produced are veteran units +"Unit_Cost" - increase the cost of building a unit of class + .aff_unit in the city by AMOUNT percent + (multiple effects are additive) + +"Building_Cost" - increase the cost of building an improvement + in the city by AMOUNT percent + (multiple effects are additive) + +"Unit_Cost_Pct" - multiply the cost of building a unit of class + .aff_unit in the city by AMOUNT percent + (multiple effects are multiplicative) + +"Building_Cost_Pct"- multiply the cost of building an improvement + in the city by AMOUNT percent + (multiple effects are multiplicative) + "Upgrade_One_Step"- upgrade one obsolete unit per turn, stepping to each intermediate type; chance to upgrade each unit is AMOUNT percent diff -Nur -Xfreecivdiff.ignore freeciv-cvs/server/cityturn.c freeciv-patched/server/cityturn.c --- freeciv-cvs/server/cityturn.c 2003-07-24 17:05:30.000000000 +0100 +++ freeciv-patched/server/cityturn.c 2003-07-24 17:05:31.000000000 +0100 @@ -951,6 +951,7 @@ static bool city_build_building(struct player *pplayer, struct city *pcity) { bool space_part; + int imp_value; if (pcity->currently_building == B_CAPITAL) { assert(pcity->shield_surplus >= 0); @@ -970,7 +971,9 @@ currently_building)); return TRUE; } - if (pcity->shield_stock >= improvement_value(pcity->currently_building)) { + + imp_value = improvement_value_adjusted(pcity->currently_building, pcity); + if (pcity->shield_stock >= imp_value) { if (pcity->currently_building == B_PALACE) { city_list_iterate(pplayer->cities, palace) if (city_got_building(palace, B_PALACE)) { @@ -991,9 +994,8 @@ space_part = FALSE; city_add_improvement(pcity, pcity->currently_building); } - pcity->before_change_shields -= - improvement_value(pcity->currently_building); - pcity->shield_stock -= improvement_value(pcity->currently_building); + pcity->before_change_shields -= imp_value; + pcity->shield_stock -= imp_value; pcity->turn_last_built = game.year; /* to eliminate micromanagement */ if (is_wonder(pcity->currently_building)) { @@ -1053,9 +1055,13 @@ **************************************************************************/ static bool city_build_unit(struct player *pplayer, struct city *pcity) { + int unit_val; + upgrade_unit_prod(pcity); - if (pcity->shield_stock >= unit_value(pcity->currently_building)) { + unit_val = unit_value_adjusted(pcity->currently_building, pcity); + + if (pcity->shield_stock >= unit_val) { int pop_cost = unit_pop_value(pcity->currently_building); /* Should we disband the city? -- Massimo */ @@ -1088,8 +1094,8 @@ /* to eliminate micromanagement, we only subtract the unit's cost */ - pcity->before_change_shields -= unit_value(pcity->currently_building); - pcity->shield_stock -= unit_value(pcity->currently_building); + pcity->before_change_shields -= unit_val; + pcity->shield_stock -= unit_val; notify_player_ex(pplayer, pcity->x, pcity->y, E_UNIT_BUILD, _("Game: %s is finished building %s."),