diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/client/control.c diplbug/client/control.c --- freeciv/client/control.c Fri May 5 17:10:48 2000 +++ diplbug/client/control.c Fri May 5 23:04:16 2000 @@ -361,7 +361,7 @@ re-checking that a popup is appropriate. If punit is NULL, just do for the next arrival in the queue. **************************************************************************/ -void process_diplomat_arrival(struct unit *punit, struct city *pcity) +void process_diplomat_arrival(struct unit *pdiplomat, int victim_id) { static struct genlist arrival_queue; static int is_init_arrival_queue = 0; @@ -375,10 +375,10 @@ is_init_arrival_queue = 1; } - if (punit && pcity) { + if (pdiplomat && victim_id) { p_ids = fc_malloc(2*sizeof(int)); - p_ids[0] = punit->id; - p_ids[1] = pcity->id; + p_ids[0] = pdiplomat->id; + p_ids[1] = victim_id; genlist_insert(&arrival_queue, p_ids, -1); } @@ -388,22 +388,35 @@ } while (genlist_size(&arrival_queue)) { - int unit_id, city_id; + int diplomat_id, victim_id; + struct city *pcity; + struct unit *punit; p_ids = genlist_get(&arrival_queue, 0); genlist_unlink(&arrival_queue, p_ids); - unit_id = p_ids[0]; - city_id = p_ids[1]; + diplomat_id = p_ids[0]; + victim_id = p_ids[1]; free(p_ids); - punit = player_find_unit_by_id(game.player_ptr, unit_id); - pcity = find_city_by_id(city_id); - - if(punit && pcity && unit_flag(punit->type, F_DIPLOMAT) && - is_diplomat_action_available(punit, DIPLOMAT_ANY_ACTION, - pcity->x, pcity->y) && - diplomat_can_do_action(punit, DIPLOMAT_ANY_ACTION, - pcity->x, pcity->y)) { - popup_diplomat_dialog(punit, pcity->x, pcity->y); + pdiplomat = player_find_unit_by_id(game.player_ptr, diplomat_id); + pcity = find_city_by_id(victim_id); + punit = find_unit_by_id(victim_id); + + if (!pdiplomat || !unit_flag(pdiplomat->type, F_DIPLOMAT)) + continue; + + if (punit + && is_diplomat_action_available(pdiplomat, DIPLOMAT_ANY_ACTION, + punit->x, punit->y) + && diplomat_can_do_action(pdiplomat, DIPLOMAT_ANY_ACTION, + punit->x, punit->y)) { + popup_diplomat_dialog(pdiplomat, punit->x, punit->y); + return; + } else if (pcity + && is_diplomat_action_available(pdiplomat, DIPLOMAT_ANY_ACTION, + pcity->x, pcity->y) + && diplomat_can_do_action(pdiplomat, DIPLOMAT_ANY_ACTION, + pcity->x, pcity->y)) { + popup_diplomat_dialog(pdiplomat, pcity->x, pcity->y); return; } } @@ -501,27 +514,29 @@ } /************************************************************************** -... - - No need to do caravan-specific stuff here any more: server does trade - routes to enemy cities automatically, and for friendly cities we wait - for the unit to enter the city. --dwp - - No need to do diplomat-specific stuff here any more: server notifies - client whenever diplomat attempts to enter enemy city. --jjm + This function is called whenever the player pressed an arrow key. + If punit is a diplomat trying to move to a tile with a unit we forward + it to popup_diplomat_dialog. + We do NOT take into account that punit might be a caravan or a diplomat + trying to move into a city; the server will handle those cases. **************************************************************************/ void request_move_unit_direction(struct unit *punit, int dx, int dy) { int dest_x, dest_y; struct unit req_unit; - dest_x=map_adjust_x(punit->x+dx); - dest_y=punit->y+dy; /* not adjusting on purpose*/ /* why? --dwp */ + dest_x = map_adjust_x(punit->x+dx); + dest_y = punit->y+dy; /* Not adjusted since if it needed to be adjusted it + would mean that we tried to move of the map... */ + + /* Catches attempts to move off map */ + if (!is_real_tile(dest_x, dest_y)) + return; - req_unit=*punit; - req_unit.x=dest_x; - req_unit.y=dest_y; + req_unit = *punit; + req_unit.x = dest_x; + req_unit.y = dest_y; send_move_unit(&req_unit); } diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/client/control.h diplbug/client/control.h --- freeciv/client/control.h Fri May 5 17:10:48 2000 +++ diplbug/client/control.h Fri May 5 22:29:04 2000 @@ -61,7 +61,7 @@ void blink_active_unit(void); void process_caravan_arrival(struct unit *punit); -void process_diplomat_arrival(struct unit *punit, struct city *pcity); +void process_diplomat_arrival(struct unit *punit, int victim_id); void key_cancel_action(void); void key_city_names_toggle(void); diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/client/packhand.c diplbug/client/packhand.c --- freeciv/client/packhand.c Fri May 5 17:10:49 2000 +++ diplbug/client/packhand.c Fri May 5 22:29:04 2000 @@ -1547,7 +1547,6 @@ void handle_diplomat_action(struct packet_diplomat_action *packet) { struct unit *pdiplomat=player_find_unit_by_id(game.player_ptr, packet->diplomat_id); - struct city *pcity=find_city_by_id(packet->target_id); if (!pdiplomat) { freelog(LOG_NORMAL, "Received bad diplomat id %d in handle_diplomat_action()", @@ -1555,15 +1554,9 @@ return; } - if (!pcity) { - freelog(LOG_NORMAL, "Received bad city id %d in handle_diplomat_action()", - packet->target_id); - return; - } - switch(packet->action_type) { case DIPLOMAT_CLIENT_POPUP_DIALOG: - process_diplomat_arrival(pdiplomat, pcity); + process_diplomat_arrival(pdiplomat, packet->target_id); break; default: freelog(LOG_NORMAL, "Received bad action %d in handle_diplomat_action()", diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/server/unithand.c diplbug/server/unithand.c --- freeciv/server/unithand.c Fri May 5 17:11:12 2000 +++ diplbug/server/unithand.c Fri May 5 23:04:45 2000 @@ -799,7 +799,8 @@ int dest_x, int dest_y, int igzoc) { int unit_id, transport_units = 1, ok; - struct unit *pdefender, *ferryboat, *bodyguard, *passenger; + struct unit *pdefender = get_defender(pplayer, punit, dest_x, dest_y); + struct unit *ferryboat, *bodyguard, *passenger; struct unit_list cargolist; struct city *pcity; @@ -827,18 +828,28 @@ return handle_unit_establish_trade(pplayer, &req); } - if (is_diplomat_unit(punit) && (pcity = map_get_city(dest_x, dest_y))) - if (city_owner(pcity) != unit_owner(punit)) { - struct packet_diplomat_action packet; - send_unit_info(unit_owner(punit), punit); - packet.target_id = pcity->id; - packet.diplomat_id = punit->id; - packet.action_type = DIPLOMAT_CLIENT_POPUP_DIALOG; - send_packet_diplomat_action(unit_owner(punit)->conn, &packet); - return 0; - } + if (is_diplomat_unit(punit) + && is_diplomat_action_available(punit, DIPLOMAT_ANY_ACTION, dest_x, dest_y)) { + struct packet_diplomat_action packet; + /* If send_unit_info the client would sometimes think that the diplomat + didn't have any moves left and so don't pop up the box. + (We are in the middle of the unit restore cycle and the unit's + movepoints have been restored, but we only send the unit info at + the end of the function. */ + send_unit_info(unit_owner(punit), punit); - pdefender = get_defender(pplayer, punit, dest_x, dest_y); + /* if is_diplomat_action_available() then there must be a city or a unit */ + if ((pcity = map_get_city(dest_x,dest_y))) + packet.target_id = pcity->id; + else if (pdefender) + packet.target_id = pdefender->id; + else + freelog(LOG_FATAL, "Bug in unithand.c"); + packet.diplomat_id = punit->id; + packet.action_type = DIPLOMAT_CLIENT_POPUP_DIALOG; + send_packet_diplomat_action(unit_owner(punit)->conn, &packet); + return 0; + } if(pdefender && pdefender->owner!=punit->owner) { if(can_unit_attack_tile(punit,dest_x , dest_y)) {