diff -Nur -Xdiff_ignore freeciv_cvs/ai/aicity.c freeciv/ai/aicity.c --- freeciv_cvs/ai/aicity.c Fri Jan 26 19:09:26 2001 +++ freeciv/ai/aicity.c Fri Feb 2 16:24:39 2001 @@ -397,6 +397,8 @@ unit_types[punit->type].name, pcity->name); /* FIXME: should be handled in server... */ pcity->shield_stock+=(get_unit_type(punit->type)->build_cost/2); + pcity->unit_disbanded_shields= + (get_unit_type(punit->type)->build_cost/2); send_city_info(pplayer, pcity); wipe_unit_safe(punit, &myiter); } diff -Nur -Xdiff_ignore freeciv_cvs/client/packhand.c freeciv/client/packhand.c --- freeciv_cvs/client/packhand.c Tue Jan 30 12:31:09 2001 +++ freeciv/client/packhand.c Fri Feb 2 15:49:04 2001 @@ -351,6 +351,8 @@ pcity->changed_from_id=packet->changed_from_id; pcity->changed_from_is_unit=packet->changed_from_is_unit; pcity->before_change_shields=packet->before_change_shields; + pcity->unit_disbanded_shields=packet->unit_disbanded_shields; + pcity->caravan_shields=packet->caravan_shields; i=0; for(y=0; yshield_stock; + int shield_stock_after_adjustment; + int orig_class; /* 0 = unit, 1 = improvement (normal), 2 = wonder */ + int new_class; + int put_penalty; // 1 = YES, 0 = NO - freelog(LOG_DEBUG, "compute change-production penalty: %s -> %s", - pcity->is_building_unit ? - unit_types[pcity->currently_building].name : - improvement_types[pcity->currently_building].name, - is_unit ? - unit_types[target].name : - improvement_types[target].name - ); - freelog(LOG_DEBUG, - "before: (stock=%d last/test=%d/%d changed=%d year=%d orig: %d %s)", - pcity->shield_stock, - pcity->turn_last_built, game_next_year(pcity->turn_last_built), - pcity->turn_changed_target, game.year, - pcity->before_change_shields, - pcity->changed_from_is_unit ? - unit_types[pcity->changed_from_id].name : - improvement_types[pcity->changed_from_id].name - ); + if (pcity->changed_from_is_unit) + orig_class=0; + else if (is_wonder(pcity->changed_from_id)) + orig_class=2; + else + orig_class=1; - /* If already building this thing, nothing to do... */ - if ((pcity->is_building_unit == is_unit) && - (pcity->currently_building == target)) { - freelog(LOG_DEBUG, "...did not change production; do nothing"); - return shield_stock_after_adjustment; - } + if (is_unit) + new_class=0; + else if (is_wonder(target)) + new_class=2; + else + new_class=1; - /* We're changing production... */ - if (((pcity->is_building_unit != is_unit) || - (!is_unit && - (is_wonder(pcity->currently_building) != is_wonder(target)))) && - (game_next_year(pcity->turn_last_built) < game.year)) { - /* We've changed "class", and it's not the turn immed after completion. */ - freelog(LOG_DEBUG, "...changed prod class in latter year"); - if (pcity->turn_changed_target != game.year) { - /* This is the first change this turn... */ - freelog(LOG_DEBUG, " ...first change this year; penalty"); - /* Compute new shield_stock after production penalty. */ - shield_stock_after_adjustment /= 2; - /* Only if really applying the penalty... */ - if (apply_it) { - /* Apply the penalty. */ - pcity->shield_stock = shield_stock_after_adjustment; - /* Only set turn_changed_target when we actually cop the penalty - - otherwise you can change to something of the same class first, - and suffer no penalty for any later changes in the same turn. */ - pcity->turn_changed_target = game.year; - } - } else if ((pcity->changed_from_is_unit == is_unit) && - (is_unit || - (is_wonder(pcity->changed_from_id) == is_wonder(target)))) { - /* This is a change back to the initial production class... */ - freelog(LOG_DEBUG, " ...revert to initial production class"); - /* Compute new shield_stock after reverting penalty. */ - shield_stock_after_adjustment = pcity->before_change_shields; - /* Only if really applying the penalty... */ - if (apply_it) { - /* Undo penalty. */ - pcity->shield_stock = shield_stock_after_adjustment; - /* Pretend we havn't changed this turn. */ - pcity->turn_changed_target = GAME_START_YEAR; - } -#ifdef DEBUG - } else { - freelog(LOG_DEBUG, " ...latter change in year; no penalty"); -#endif - } -#ifdef DEBUG - } else { - freelog(LOG_DEBUG, "...same class or first year; no penalty"); -#endif - } + put_penalty = (orig_class != new_class && + game_next_year(pcity->turn_last_built) < game.year)? 1 : 0; + + if (put_penalty) + shield_stock_after_adjustment = pcity->before_change_shields/2; + else + shield_stock_after_adjustment = pcity->before_change_shields; - freelog(LOG_DEBUG, - "--> %-3d (stock=%d last/test=%d/%d changed=%d year=%d orig: %d %s)", - shield_stock_after_adjustment, - pcity->shield_stock, - pcity->turn_last_built, game_next_year(pcity->turn_last_built), - pcity->turn_changed_target, game.year, - pcity->before_change_shields, - pcity->changed_from_is_unit ? - unit_types[pcity->changed_from_id].name : - improvement_types[pcity->changed_from_id].name - ); + /* Do not put penalty on these. It shouldn't matter whether you disband unit + before or after changing production...*/ + shield_stock_after_adjustment += pcity->unit_disbanded_shields; + if (new_class == 2) /* No penalty! */ + shield_stock_after_adjustment += pcity->caravan_shields; + else /* Same as you had disbanded caravans. 50 percent penalty is logical! */ + shield_stock_after_adjustment += pcity->caravan_shields/2; + + if (apply_it) { + pcity->shield_stock = shield_stock_after_adjustment; + + if (new_class != orig_class) + pcity->turn_changed_target = game.year; + /* Do we really need this at all? */ + else + pcity->turn_changed_target = GAME_START_YEAR; + /* Pretend we have changed nothing */ + } + return shield_stock_after_adjustment; } diff -Nur -Xdiff_ignore freeciv_cvs/common/city.h freeciv/common/city.h --- freeciv_cvs/common/city.h Fri Jan 26 19:09:26 2001 +++ freeciv/common/city.h Fri Feb 2 15:34:22 2001 @@ -215,6 +215,8 @@ int turn_changed_target; /* Suffer shield loss at most once per turn */ int changed_from_id; /* If changed this turn, what changed from (id) */ int changed_from_is_unit; /* If changed this turn, what changed from (unit?) */ + int unit_disbanded_shields; /* If you disband unit in a city. Count them */ + int caravan_shields; /* If caravan has helped city to build wonder. */ int before_change_shields; /* If changed this turn, shields before penalty */ int anarchy; /* anarchy rounds count */ int rapture; /* rapture rounds count */ diff -Nur -Xdiff_ignore freeciv_cvs/common/packets.c freeciv/common/packets.c --- freeciv_cvs/common/packets.c Tue Jan 30 12:31:05 2001 +++ freeciv/common/packets.c Fri Feb 2 15:50:57 2001 @@ -2237,6 +2237,11 @@ cptr=put_uint16(cptr, req->before_change_shields); } +if (pc && has_capability("production_change_fix2", pc->capability)) { + cptr=put_uint16(cptr, req->unit_disbanded_shields); + cptr=put_uint16(cptr, req->caravan_shields); +} + /* when removing "worklist_true_ids" capability, may want to remove the 'pc' argument (?) */ cptr=put_worklist(cptr, &req->worklist, pc, 1); @@ -2325,6 +2330,14 @@ packet->turn_changed_target = GAME_START_YEAR; packet->changed_from_id = packet->currently_building; packet->before_change_shields = packet->shield_stock; +} + +if (pc && has_capability("production_change_fix2", pc->capability)) { + iget_uint16(&iter, &packet->unit_disbanded_shields); + iget_uint16(&iter, &packet->caravan_shields); +} else { + packet->unit_disbanded_shields = 0; + packet->caravan_shields = 0; } /* when removing "worklist_true_ids" capability, diff -Nur -Xdiff_ignore freeciv_cvs/common/packets.h freeciv/common/packets.h --- freeciv_cvs/common/packets.h Tue Jan 30 12:31:05 2001 +++ freeciv/common/packets.h Fri Feb 2 15:38:26 2001 @@ -346,6 +346,8 @@ int changed_from_id; int changed_from_is_unit; int before_change_shields; + int unit_disbanded_shields; + int caravan_shields; struct worklist worklist; diff -Nur -Xdiff_ignore freeciv_cvs/server/cityhand.c freeciv/server/cityhand.c --- freeciv_cvs/server/cityhand.c Fri Jan 26 19:09:20 2001 +++ freeciv/server/cityhand.c Fri Feb 2 16:19:56 2001 @@ -197,6 +197,8 @@ pcity->changed_from_id = 0; pcity->changed_from_is_unit = 0; pcity->before_change_shields = 0; + pcity->unit_disbanded_shields = 0; + pcity->caravan_shields = 0; pcity->anarchy=0; pcity->rapture=0; @@ -505,6 +507,8 @@ pplayer->economic.gold-=cost; if (pcity->shield_stock < total){ + /* It is no longer possible to change production. No need to worry + about pcity->before_change_shields here :) */ pcity->shield_stock=total; /* AI wants this -- Syela */ pcity->did_buy=1; /* !PS: no need to set buy flag otherwise */ } @@ -1032,6 +1036,8 @@ packet->changed_from_id=pcity->changed_from_id; packet->changed_from_is_unit=pcity->changed_from_is_unit; packet->before_change_shields=pcity->before_change_shields; + packet->unit_disbanded_shields=pcity->unit_disbanded_shields; + packet->caravan_shields=pcity->caravan_shields; copy_worklist(&packet->worklist, pcity->worklist); packet->diplomat_investigate=dipl_invest; diff -Nur -Xdiff_ignore freeciv_cvs/server/citytools.c freeciv/server/citytools.c --- freeciv_cvs/server/citytools.c Mon Jan 15 14:42:46 2001 +++ freeciv/server/citytools.c Fri Feb 2 15:53:57 2001 @@ -1053,6 +1053,7 @@ } } pcity->before_change_shields = 0; + nullify_caravan_and_disband_plus(pcity); pcity->shield_stock = 0; } diff -Nur -Xdiff_ignore freeciv_cvs/server/cityturn.c freeciv/server/cityturn.c --- freeciv_cvs/server/cityturn.c Tue Jan 30 12:31:06 2001 +++ freeciv/server/cityturn.c Fri Feb 2 16:28:06 2001 @@ -82,7 +82,7 @@ static void disband_city(struct city *pcity); -static void begin_city_turn(struct player *pplayer, struct city *pcity); +static void define_orig_production_values(struct city *pcity); static int update_city_activity(struct player *pplayer, struct city *pcity); static void worker_loop(struct city *pcity, int *foodneed, @@ -820,7 +820,7 @@ void begin_cities_turn(struct player *pplayer) { city_list_iterate(pplayer->cities, pcity) - begin_city_turn(pplayer, pcity); + define_orig_production_values(pcity); city_list_iterate_end; } @@ -1291,11 +1291,16 @@ } unit_list_iterate_end; } - + + /* Now we confirm changes made last turn. */ pcity->shield_stock+=pcity->shield_surplus; + pcity->before_change_shields=pcity->shield_stock; + nullify_caravan_and_disband_plus(); + if (!pcity->is_building_unit) { if (pcity->currently_building==B_CAPITAL) { pplayer->economic.gold+=pcity->shield_surplus; + pcity->before_change_shields=0; pcity->shield_stock=0; } upgrade_building_prod(pcity); @@ -1305,7 +1310,8 @@ pcity->name,get_impr_name_ex(pcity, pcity->currently_building)); return 1; } - if (pcity->shield_stock>=improvement_value(pcity->currently_building)) { + if (pcity->before_change_shields>= + improvement_value(pcity->currently_building)) { if (pcity->currently_building==B_PALACE) { city_list_iterate(pplayer->cities, palace) if (city_got_building(palace, B_PALACE)) { @@ -1326,7 +1332,9 @@ space_part = 0; pcity->improvements[pcity->currently_building]=1; } - pcity->shield_stock-=improvement_value(pcity->currently_building); + pcity->before_change_shields-= + improvement_value(pcity->currently_building); + pcity->shield_stock-=improvement_value(pcity->currently_building); pcity->turn_last_built = game.year; /* to eliminate micromanagement */ if(is_wonder(pcity->currently_building)) { @@ -1391,7 +1399,7 @@ /* FIXME: F_CITIES should be changed to any unit * that 'contains' 1 (or more) pop -- sjolie */ - if(pcity->shield_stock>=unit_value(pcity->currently_building)) { + if(pcity->before_change_shields>=unit_value(pcity->currently_building)) { if (unit_flag(pcity->currently_building, F_CITIES)) { if (pcity->size==1) { @@ -1417,7 +1425,8 @@ do_make_unit_veteran(pcity, pcity->currently_building), pcity->id, -1); /* to eliminate micromanagement, we only subtract the unit's cost */ - pcity->shield_stock-=unit_value(pcity->currently_building); + pcity->before_change_shields-=unit_value(pcity->currently_building); + pcity->shield_stock-=unit_value(pcity->currently_building); if (city_built_city_builder) { pcity->size--; @@ -1697,13 +1706,13 @@ /************************************************************************** Called every turn, at beginning of turn, for every city. **************************************************************************/ -static void begin_city_turn(struct player *pplayer, struct city *pcity) +static void define_orig_production_values(struct city *pcity) { /* remember what this city is building at start of turn, so user can switch production back without penalty */ pcity->changed_from_id = pcity->currently_building; pcity->changed_from_is_unit = pcity->is_building_unit; - pcity->before_change_shields = pcity->shield_stock; + freelog(LOG_DEBUG, "In %s, building %s. Beg of Turn shields = %d", pcity->name, @@ -1712,6 +1721,12 @@ improvement_types[pcity->changed_from_id].name, pcity->before_change_shields ); +} + +void nullify_caravan_and_disband_plus(struct city *pcity) +{ + pcity->unit_disbanded_shields=0; + pcity->caravan_shields=0; } /************************************************************************** diff -Nur -Xdiff_ignore freeciv_cvs/server/cityturn.h freeciv/server/cityturn.h --- freeciv_cvs/server/cityturn.h Thu Dec 21 14:38:17 2000 +++ freeciv/server/cityturn.h Fri Feb 2 13:11:18 2001 @@ -38,4 +38,6 @@ void remove_obsolete_buildings_city(struct city *pcity, int refresh); void remove_obsolete_buildings(struct player *plr); +void nullify_caravan_and_disband_plus(); + #endif /* FC__CITYTURN_H */ diff -Nur -Xdiff_ignore freeciv_cvs/server/diplomats.c freeciv/server/diplomats.c --- freeciv_cvs/server/diplomats.c Mon Jan 15 14:42:47 2001 +++ freeciv/server/diplomats.c Fri Feb 2 16:11:50 2001 @@ -803,6 +803,8 @@ pcity->name, get_nation_name (pplayer->nation)); pcity->shield_stock = 0; + pcity->before_change_shields=0; + nullify_caravan_and_disband_plus(pcity); /* You get a technology advance, too! */ get_a_tech (pplayer, cplayer); @@ -981,6 +983,8 @@ /* Do it. */ pcity->shield_stock = 0; + pcity->before_change_shields = 0; /* Make it impossible to recover! */ + nullify_caravan_and_disband_plus(pcity); /* Report it. */ if (pcity->is_building_unit) prod = unit_name (pcity->currently_building); diff -Nur -Xdiff_ignore freeciv_cvs/server/savegame.c freeciv/server/savegame.c --- freeciv_cvs/server/savegame.c Thu Jan 4 14:39:22 2001 +++ freeciv/server/savegame.c Wed Jan 31 14:20:21 2001 @@ -776,7 +776,13 @@ pcity->before_change_shields= secfile_lookup_int_default(file, pcity->shield_stock, "player%d.c%d.before_change_shields", plrno, i); - + pcity->unit_disbanded_shields= + secfile_lookup_int_default(file, 0, + "player%d.c%d.unit_disbanded_shields", plrno, i); + pcity->caravan_shields= + secfile_lookup_int_default(file, 0, + "player%d.c%d.caravan_shields", plrno, i); + pcity->did_buy=secfile_lookup_int(file, "player%d.c%d.did_buy", plrno,i); pcity->did_sell = @@ -1418,6 +1424,11 @@ "player%d.c%d.changed_from_is_unit", plrno, i); secfile_insert_int(file, pcity->before_change_shields, "player%d.c%d.before_change_shields", plrno, i); + secfile_insert_int(file, pcity->unit_disbanded_shields, + "player%d.c%d.unit_disbanded_shields", plrno, i); + secfile_insert_int(file, pcity->caravan_shields, + "player%d.c%d.caravan_shields", plrno, i); + secfile_insert_int(file, pcity->anarchy, "player%d.c%d.anarchy", plrno,i); secfile_insert_int(file, pcity->rapture, "player%d.c%d.rapture", plrno,i); secfile_insert_int(file, pcity->was_happy, "player%d.c%d.was_happy", plrno,i); diff -Nur -Xdiff_ignore freeciv_cvs/server/unithand.c freeciv/server/unithand.c --- freeciv_cvs/server/unithand.c Thu Jan 11 14:42:04 2001 +++ freeciv/server/unithand.c Fri Feb 2 16:13:28 2001 @@ -340,6 +340,8 @@ if((punit=player_find_unit_by_id(pplayer, req->unit_id))) { if ((pcity=map_get_city(punit->x, punit->y))) { pcity->shield_stock+=(get_unit_type(punit->type)->build_cost/2); + /* If we change production later at this turn. No penalty is added. */ + pcity->unit_disbanded_shields+=(get_unit_type(punit->type)->build_cost/2); send_city_info(pplayer, pcity); } wipe_unit_safe(punit, iter); @@ -1144,10 +1146,13 @@ /* we're there! */ pcity_dest->shield_stock+=50; - if (build_points_left(pcity_dest) < 0) { + pcity_dest->caravan_shields+=50; /*If we change production we dont lose them*/ + + /*if (build_points_left(pcity_dest) < 0) { pcity_dest->shield_stock = improvement_value(pcity_dest->currently_building); - } - + }*/ + /* No need for this. Overproduction should take care of this -- Zamar */ + conn_list_do_buffer(&pplayer->connections); notify_player_ex(pplayer, pcity_dest->x, pcity_dest->y, E_NOEVENT, _("Game: Your %s helps build the %s in %s (%d remaining)."),