diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/common/unit.c transfer_problems/common/unit.c --- freeciv/common/unit.c Mon Apr 10 17:55:20 2000 +++ transfer_problems/common/unit.c Mon Apr 10 18:29:28 2000 @@ -274,42 +274,45 @@ } /************************************************************************** -... +Check for any free space on pplayer's transporters at (x,y). +(Return number of units which may be added to transporters to fill them.) **************************************************************************/ int is_transporter_with_free_space(struct player *pplayer, int x, int y) { - int none_transporters=0, total_capacity=0; + int availability = 0; unit_list_iterate(map_get_tile(x, y)->units, punit) { - if(is_ground_units_transport(punit)) - total_capacity+=get_transporter_capacity(punit); - else if (is_ground_unit(punit)) - none_transporters++; + if (punit->owner == pplayer->player_no) { + if (is_ground_units_transport(punit)) + availability += get_transporter_capacity(punit); + else if (is_ground_unit(punit)) + availability--; + } } unit_list_iterate_end; - - return(total_capacity>none_transporters ? total_capacity-none_transporters : 0); + + return (availability > 0 ? availability : 0); } /************************************************************************** -The above one isn't quite what I want - Kris -Specifically: only pplayer's transports count; only returns true/false; -and returns true if (capacity == passengers). --dwp +Check for enough pplayer's transporters to carry pplayer's ground units at (x,y). +(Return true if capacity of transporters >= number of ground units.) **************************************************************************/ -int is_enough_transporter_space (struct player *pplayer, int x, int y) +int is_enough_transporter_space(struct player *pplayer, int x, int y) { - int none_transporters=0, total_capacity=0; - + int availability = 0; + unit_list_iterate(map_get_tile(x, y)->units, punit) { - if(is_ground_units_transport(punit) - && punit->owner == pplayer->player_no) - total_capacity+=get_transporter_capacity(punit); - else if (is_ground_unit(punit)) - none_transporters++; + if (punit->owner == pplayer->player_no) { + if (is_ground_units_transport(punit)) + availability += get_transporter_capacity(punit); + else if (is_ground_unit(punit)) + availability--; + } } unit_list_iterate_end; - - return(total_capacity>=none_transporters ? 1 : 0); + + return (availability >= 0 ? 1 : 0); } diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/server/citytools.c transfer_problems/server/citytools.c --- freeciv/server/citytools.c Thu Apr 13 21:14:50 2000 +++ transfer_problems/server/citytools.c Thu Apr 13 21:15:33 2000 @@ -605,6 +605,7 @@ struct city *pcity, struct city *vcity, int kill_outside, int verbose, int resolve_stack) { + int ux, uy; int x = vcity->x; int y = vcity->y; @@ -628,7 +629,6 @@ * cities or maybe destroyed */ unit_list_iterate(vcity->units_supported, vunit) { struct city* new_home_city = map_get_city(vunit->x, vunit->y); - x = vunit->x; y = vunit->y; if(new_home_city) { /* unit is in another city: make that the new homecity, unless that city is actually the same city (happens if disbanding) */ @@ -675,12 +675,15 @@ vunit->veteran, pcity->id, vunit->moves_left, vunit->hp); } + + ux = vunit->x; + uy = vunit->y; wipe_unit_spec_safe(0, vunit, NULL, 0); - - if (resolve_stack) { - /* Now make sure that if we just deleted a transporter the carried units are - not left floating in the water */ - resolve_unit_stack(x,y,1); + + if (resolve_stack && !new_home_city) { + /* Now make sure that if we just deleted a transporter the + carried units are not left floating in the water */ + resolve_unit_stack(ux, uy, 1); } } unit_list_iterate_end; @@ -952,9 +955,12 @@ a unit from another city, and both cities join the rebellion. We resolved stack conflicts for each city we would teleport the first of the units we met since the other would have another owner */ - if(!(pnewcity = transfer_city(cplayer, pplayer, pcity, -1, 0, 1))){ + if(!(pnewcity = transfer_city(cplayer, pplayer, pcity, -1, 0, 0))){ freelog(LOG_VERBOSE, "Transfer city returned no city - aborting civil war."); + unit_list_iterate(pplayer->units, punit) + resolve_unit_stack(punit->x, punit->y, 0); + unit_list_iterate_end; return; } diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/server/unithand.c transfer_problems/server/unithand.c --- freeciv/server/unithand.c Mon Apr 10 17:55:25 2000 +++ transfer_problems/server/unithand.c Mon Apr 10 18:26:02 2000 @@ -1193,6 +1193,8 @@ get_nation_name_plural(pplayer->nation)); remove_city_from_minimap(pcity->x, pcity->y); remove_city(pcity); + if (do_civil_war) + civil_war(cplayer); return; } diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/server/unittools.c transfer_problems/server/unittools.c --- freeciv/server/unittools.c Thu Apr 13 21:14:50 2000 +++ transfer_problems/server/unittools.c Thu Apr 13 21:15:33 2000 @@ -733,8 +733,9 @@ void resolve_unit_stack(int x, int y, int verbose) { - struct unit *punit = unit_list_get(&map_get_tile(x, y)->units, 0), *cunit; - + struct unit *punit, *cunit; + + punit = unit_list_get(&map_get_tile(x, y)->units, 0); if (!punit) return; cunit = is_enemy_unit_on_tile(x, y, punit->owner); @@ -767,6 +768,8 @@ } punit = unit_list_get(&map_get_tile(x, y)->units, 0); + if (!punit) + break; cunit = is_enemy_unit_on_tile(x, y, punit->owner); } @@ -777,24 +780,27 @@ if(!punit && cunit) punit = cunit; - if(punit && map_get_terrain(punit->x, punit->y)==T_OCEAN && - !is_enough_transporter_space(get_player(punit->owner), x, y)){ - unit_list_iterate(map_get_tile(x, y)->units, vunit){ - struct city *vcity = find_closest_owned_city(get_player(vunit->owner), x, y); - if(is_ground_unit(vunit)){ - teleport_unit_to_city(vunit, vcity, 0); - freelog(LOG_VERBOSE, "Teleported %s's %s to %s" - " as there is no transport space on square (%d, %d)", - get_player(vunit->owner)->name, unit_name(vunit->type), - vcity->name, x, y); - if (verbose) { - notify_player(get_player(vunit->owner), - _("Game: Teleported your %s to %s as there is" - " no transport space on square (%d, %d)."), - unit_name(vunit->type), vcity->name, x, y); + if(punit && map_get_terrain(punit->x, punit->y)==T_OCEAN) { + while(!is_enough_transporter_space(get_player(punit->owner), x, y)) { + unit_list_iterate(map_get_tile(x, y)->units, vunit) { + if(is_ground_unit(vunit)) { + struct city *vcity = + find_closest_owned_city(get_player(vunit->owner), x, y); + teleport_unit_to_city(vunit, vcity, 0); + freelog(LOG_VERBOSE, "Teleported %s's %s to %s" + " as there is no transport space on square (%d, %d)", + get_player(vunit->owner)->name, unit_name(vunit->type), + vcity->name, x, y); + if (verbose) { + notify_player(get_player(vunit->owner), + _("Game: Teleported your %s to %s as there is" + " no transport space on square (%d, %d)."), + unit_name(vunit->type), vcity->name, x, y); + } + break; /* break out of unit_list_iterate loop */ } } + unit_list_iterate_end; } - unit_list_iterate_end; } }