Index: server/unittools.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v retrieving revision 1.205 diff -u -r1.205 unittools.c --- server/unittools.c 2003/01/12 22:36:23 1.205 +++ server/unittools.c 2003/01/13 12:38:50 @@ -104,18 +104,23 @@ } /************************************************************************** - Unit can't attack if: + Unit can't attack if: 1) it doesn't have any attack power. 2) it's not a fighter and the defender is a flying unit (except city/airbase). 3) if it's not a marine (and ground unit) and it attacks from ocean. 4) a ground unit can't attack a ship on an ocean square (except marines). 5) the players are not at war. + 6) a city there is owned by non-attack player + + Does NOT check: + 1) Moves left **************************************************************************/ bool can_unit_attack_unit_at_tile(struct unit *punit, struct unit *pdefender, - int dest_x, int dest_y) + int dest_x, int dest_y) { enum tile_terrain_type fromtile; enum tile_terrain_type totile; + struct city *pcity = map_get_city(dest_x, dest_y); fromtile = map_get_terrain(punit->x, punit->y); totile = map_get_terrain(dest_x, dest_y); @@ -150,6 +155,10 @@ /* Shore bombardement */ if (is_ocean(fromtile) && is_sailing_unit(punit) && !is_ocean(totile)) { return (get_attack_power(punit)>0); + } + + if (pcity && !pplayers_at_war(city_owner(pcity), unit_owner(punit))) { + return FALSE; } return TRUE; Index: server/unithand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v retrieving revision 1.246 diff -u -r1.246 unithand.c --- server/unithand.c 2003/01/09 02:36:38 1.246 +++ server/unithand.c 2003/01/13 12:38:50 @@ -980,6 +980,17 @@ /*** Try to attack if there is an enemy unit on the target tile ***/ if (pdefender && pplayers_at_war(unit_owner(punit), unit_owner(pdefender))) { + if (pcity && !pplayers_at_war(city_owner(pcity), unit_owner(punit))) { + notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT, + _("Game: Can't attack %s's unit in the city of %s " + "because you are not at war with %s."), + unit_owner(pdefender)->name, + pcity->name, + city_owner(pcity)->name); + how_to_declare_war(pplayer); + return FALSE; + } + if (!can_unit_attack_tile(punit, dest_x , dest_y)) { notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT, _("Game: You can't attack there.")); @@ -991,18 +1002,10 @@ _("Game: This unit has no moves left.")); return FALSE; } - - if (pcity && !pplayers_at_war(city_owner(pcity), unit_owner(punit))) { - notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT, - _("Game: Can't attack %s's unit in the city of %s " - "because you are not at war with %s."), - unit_owner(pdefender)->name, - pcity->name, - city_owner(pcity)->name); - how_to_declare_war(pplayer); - return FALSE; - } + /* FIXME: This code will never activate for AI players, and for + * human players the server-side goto implementation should be + * obsoleted for client usage. So in time, remove the code below. */ if (punit->activity == ACTIVITY_GOTO && !same_pos(punit->goto_dest_x, punit->goto_dest_y, dest_x, dest_y)) { notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT,