diff -udarbB -X freeciv/diff_ignore freeciv/ai/aiunit.c freeciv.mod/ai/aiunit.c --- freeciv/ai/aiunit.c Wed Jan 10 19:50:44 2001 +++ freeciv.mod/ai/aiunit.c Sat Jan 13 00:51:31 2001 @@ -318,7 +318,7 @@ if (unknown > most_unknown && (landnear || !unit_flag(punit->type, F_TRIREME)) && map_get_continent(x1, y1) == con - && can_unit_move_to_tile(punit, x1, y1, 0) + && can_unit_move_to_tile(punit, x1, y1, 0, FALSE, FALSE) && !((pcity = map_get_city(x1,y1)) && (unit_flag(punit->type, F_DIPLOMAT) || unit_flag(punit->type, F_CARAVAN))) @@ -330,7 +330,8 @@ } square_iterate_end; if (most_unknown > 0) { /* a tile have unexplored territory adjacent */ - int res = handle_unit_move_request(punit, best_x, best_y, FALSE, FALSE); + int res = handle_unit_move_request(punit, best_x, best_y, FALSE, + FALSE,FALSE,FALSE); if (!res) /* This shouldn't happen */ break; if (!player_find_unit_by_id(pplayer, id)) @@ -776,7 +777,7 @@ "Stationary escort @(%d,%d) received %d best @(%d,%d)", punit->x, punit->y, i, x, y); if (i >= 40 * SHIELD_WEIGHTING) - handle_unit_move_request(punit, x, y, FALSE, FALSE); + handle_unit_move_request(punit, x, y, FALSE, FALSE, FALSE, FALSE); /* otherwise don't bother, but free cities are free cities and must be snarfed. -- Syela */ } if (aunit && unit_list_find(&map_get_tile(x, y)->units, id) && aunit->ai.bodyguard) @@ -967,7 +968,8 @@ "Bodyguard at (%d, %d) is adjacent to (%d, %d)", i, j, punit->x, punit->y); if (aunit->moves_left) return(0); - else return handle_unit_move_request(punit, i, j, FALSE, FALSE); + else return handle_unit_move_request(punit, i, j, FALSE, + FALSE, FALSE, FALSE); } unit_list_iterate_end; } /* end j */ @@ -1187,7 +1189,8 @@ /* aggro defense goes here -- Syela */ ai_military_findvictim(pplayer, punit, &dest_x, &dest_y); punit->ai.ai_role=AIUNIT_NONE; - handle_unit_move_request(punit, dest_x, dest_y, FALSE, FALSE); + handle_unit_move_request(punit, dest_x, dest_y, FALSE, + FALSE, FALSE, FALSE); /* might bash someone */ } else { freelog(LOG_DEBUG, "GOHOME(%d,%d)", @@ -1578,7 +1581,8 @@ freelog(LOG_DEBUG, "%s's %s at (%d, %d) bashing (%d, %d)", pplayer->name, unit_types[punit->type].name, punit->x, punit->y, dest_x, dest_y); - handle_unit_move_request(punit, dest_x, dest_y, FALSE, FALSE); + handle_unit_move_request(punit, dest_x, dest_y, FALSE, + FALSE, FALSE, FALSE); punit = find_unit_by_id(id); if (punit) flag = punit->moves_left; else flag = 0; } @@ -1641,7 +1645,7 @@ } else { req.unit_id = punit->id; req.city_id = pcity->id; - handle_unit_establish_trade(pplayer, &req); + handle_unit_establish_trade(pplayer, &req, FALSE, FALSE); } } } @@ -2297,7 +2301,7 @@ y = map_adjust_x(leader->y + dy); if (warmap.cost[x][y] > safest - && can_unit_move_to_tile(leader, x, y, FALSE)) { + && can_unit_move_to_tile(leader, x, y, FALSE, FALSE, FALSE)) { safest = warmap.cost[x][y]; freelog(LOG_DEBUG, "Barbarian leader: safest is %d, %d, safeness %d", x, y, safest); diff -udarbB -X freeciv/diff_ignore freeciv/client/civclient.c freeciv.mod/client/civclient.c --- freeciv/client/civclient.c Sun Jan 7 14:09:56 2001 +++ freeciv.mod/client/civclient.c Sat Jan 13 00:51:56 2001 @@ -361,6 +361,10 @@ handle_conn_info((struct packet_conn_info *)packet); break; + case PACKET_RESULT: + handle_result((struct packet_generic_integer *)packet); + break; + default: freelog(LOG_ERROR, "Received unknown packet (type %d) from server!", type); /* Old clients (<= some 1.11.5-devel, capstr +1.11) used to exit() @@ -418,6 +422,8 @@ move.unid=punit->id; move.x=punit->x; move.y=punit->y; + move.dry_run=FALSE; + move.report_result=TRUE; send_packet_move_unit(&aconnection, &move); } diff -udarbB -X freeciv/diff_ignore freeciv/client/packhand.c freeciv.mod/client/packhand.c --- freeciv/client/packhand.c Wed Jan 10 22:24:06 2001 +++ freeciv.mod/client/packhand.c Sat Jan 13 00:51:31 2001 @@ -2164,3 +2164,11 @@ popup_sabotage_dialog(pcity); } } + +/************************************************************************** +... +**************************************************************************/ +void handle_result(struct packet_generic_integer *packet) +{ + freelog(LOG_DEBUG,"Got result %d",packet->value); +} diff -udarbB -X freeciv/diff_ignore freeciv/client/packhand.h freeciv.mod/client/packhand.h --- freeciv/client/packhand.h Sun Aug 27 08:57:22 2000 +++ freeciv.mod/client/packhand.h Sat Jan 13 00:51:31 2001 @@ -58,5 +58,6 @@ void handle_ruleset_game(struct packet_ruleset_game *packet); void handle_diplomat_action(struct packet_diplomat_action *packet); void handle_sabotage_list(struct packet_sabotage_list *packet); +void handle_result(struct packet_generic_integer *packet); #endif /* FC__PACKHAND_H */ diff -udarbB -X freeciv/diff_ignore freeciv/common/packets.c freeciv.mod/common/packets.c --- freeciv/common/packets.c Fri Dec 15 18:56:06 2000 +++ freeciv.mod/common/packets.c Sat Jan 13 00:51:31 2001 @@ -247,6 +247,7 @@ case PACKET_ADVANCE_FOCUS: case PACKET_PLAYER_CANCEL_PACT: case PACKET_PLAYER_REMOVE_VISION: + case PACKET_RESULT: return receive_packet_generic_integer(pc); case PACKET_ALLOC_NATION: @@ -2586,6 +2587,8 @@ cptr=put_uint8(cptr, request->x); cptr=put_uint8(cptr, request->y); cptr=put_uint16(cptr, request->unid); + cptr=put_uint8(cptr, request->dry_run); + cptr=put_uint8(cptr, request->report_result); put_uint16(buffer, cptr-buffer); return send_connection_data(pc, buffer, cptr-buffer); @@ -2607,6 +2610,8 @@ iget_uint8(&iter, &packet->x); iget_uint8(&iter, &packet->y); iget_uint16(&iter, &packet->unid); + iget_uint8(&iter, &packet->dry_run); + iget_uint8(&iter, &packet->report_result); pack_iter_end(&iter, pc); remove_packet_from_buffer(pc->buffer); diff -udarbB -X freeciv/diff_ignore freeciv/common/packets.h freeciv.mod/common/packets.h --- freeciv/common/packets.h Sat Oct 28 00:20:09 2000 +++ freeciv.mod/common/packets.h Sat Jan 13 00:51:31 2001 @@ -115,6 +115,7 @@ PACKET_PLAYER_REMOVE_VISION, PACKET_GOTO_ROUTE, PACKET_PATROL_ROUTE, + PACKET_RESULT, PACKET_LAST /* leave this last */ }; @@ -270,15 +271,14 @@ /********************************************************* packet represents a request to the server, for moving the -units with the corresponding id's from the unids array, -to the position x,y -unids[] is a compressed array, containing garbage after -last 0 id. +unit with the corresponding id to the position x,y. +If dry_run is set the server will not carry out the +movement. If report_result the server will send a +PACKET_RESULT back. *********************************************************/ struct packet_move_unit { - int x, y, unid; + int x, y, unid, dry_run, report_result; }; - /********************************************************* Only in freeciv.mod/common: result.h Only in freeciv.mod/: make.log diff -udarbB -X freeciv/diff_ignore freeciv/server/barbarian.c freeciv.mod/server/barbarian.c --- freeciv/server/barbarian.c Tue Jan 9 00:44:31 2001 +++ freeciv.mod/server/barbarian.c Sat Jan 13 00:51:31 2001 @@ -253,7 +253,8 @@ do { do rand_neighbour(x, y, &xu, &yu); while( !is_free_land(xu, yu, me) ); - } while( !handle_unit_move_request(punit2, xu, yu, TRUE, FALSE) ); + } while( !handle_unit_move_request(punit2, xu, yu, TRUE, + FALSE, FALSE, FALSE) ); freelog(LOG_DEBUG, "Moved barbarian unit from %d %d to %d, %d", x,y,xu,yu); } } @@ -267,8 +268,9 @@ send_unit_info( 0, punit2); while(1) { rand_neighbour(x, y, &xu, &yu); - if( can_unit_move_to_tile(punit2, xu, yu, TRUE) ) break; - if( can_unit_move_to_tile(punit2, xb, yb, TRUE) ) { + if( can_unit_move_to_tile(punit2, xu, yu, TRUE, FALSE, FALSE) ) + break; + if( can_unit_move_to_tile(punit2, xb, yb, TRUE, FALSE, FALSE) ) { xu = xb; yu = yb; break; } @@ -279,7 +281,7 @@ break; } } - handle_unit_move_request(punit2, xu, yu, TRUE, FALSE); + handle_unit_move_request(punit2, xu, yu, TRUE, FALSE, FALSE, FALSE); } unit_list_iterate_end; } diff -udarbB -X freeciv/diff_ignore freeciv/server/diplomats.c freeciv.mod/server/diplomats.c --- freeciv/server/diplomats.c Wed Jan 10 22:24:09 2001 +++ freeciv.mod/server/diplomats.c Sat Jan 13 00:51:31 2001 @@ -466,7 +466,8 @@ /* Now, try to move the briber onto the victim's square. */ diplomat_id = pdiplomat->id; - if (!handle_unit_move_request(pdiplomat, victim_x, victim_y, FALSE, FALSE)) { + if (!handle_unit_move_request(pdiplomat, victim_x, victim_y, FALSE, + FALSE, FALSE, FALSE)) { pdiplomat->moves_left = 0; } if (player_find_unit_by_id(pplayer, diplomat_id)) { diff -udarbB -X freeciv/diff_ignore freeciv/server/gotohand.c freeciv.mod/server/gotohand.c --- freeciv/server/gotohand.c Tue Jan 9 00:44:33 2001 +++ freeciv.mod/server/gotohand.c Sat Jan 13 00:51:31 2001 @@ -1194,7 +1194,7 @@ return; last_tile = same_pos(x, y, punit->goto_dest_x, punit->goto_dest_y); if (!handle_unit_move_request(punit, x, y, FALSE, - !(last_tile && trigger_special_ability))) { + !(last_tile && trigger_special_ability), FALSE, FALSE)) { freelog(LOG_DEBUG, "Couldn't handle it."); if (punit->moves_left) { punit->activity=ACTIVITY_IDLE; diff -udarbB -X freeciv/diff_ignore freeciv/server/srv_main.c freeciv.mod/server/srv_main.c --- freeciv/server/srv_main.c Tue Jan 9 00:44:35 2001 +++ freeciv.mod/server/srv_main.c Sat Jan 13 00:51:31 2001 @@ -1041,7 +1041,8 @@ break; case PACKET_UNIT_ESTABLISH_TRADE: - handle_unit_establish_trade(pplayer, (struct packet_unit_request *)packet); + handle_unit_establish_trade(pplayer, (struct packet_unit_request *)packet, + FALSE, FALSE); break; case PACKET_UNIT_HELP_BUILD_WONDER: diff -udarbB -X freeciv/diff_ignore freeciv/server/unithand.c freeciv.mod/server/unithand.c --- freeciv/server/unithand.c Wed Jan 10 22:24:09 2001 +++ freeciv.mod/server/unithand.c Sat Jan 13 00:51:31 2001 @@ -32,6 +32,7 @@ #include "rand.h" #include "support.h" #include "unit.h" +#include "result.h" #include "cityhand.h" #include "citytools.h" @@ -278,7 +279,8 @@ case DIPLOMAT_MOVE: if(pcity && diplomat_can_do_action(pdiplomat, DIPLOMAT_MOVE, pcity->x, pcity->y)) { - handle_unit_move_request(pdiplomat, pcity->x, pcity->y, FALSE, TRUE); + handle_unit_move_request(pdiplomat, pcity->x, pcity->y, + FALSE, TRUE, FALSE, FALSE); } break; case DIPLOMAT_STEAL: @@ -473,7 +475,8 @@ if(punit) { if (!same_pos(punit->x, punit->y, pinfo->x, pinfo->y)) { punit->ai.control=0; - handle_unit_move_request(punit, pinfo->x, pinfo->y, FALSE, FALSE); + handle_unit_move_request(punit, pinfo->x, pinfo->y, FALSE, + FALSE, FALSE, FALSE); } else if(punit->activity!=pinfo->activity || punit->activity_target!=pinfo->activity_target || @@ -499,7 +502,12 @@ punit=player_find_unit_by_id(pplayer, pmove->unid); if(punit) { - handle_unit_move_request(punit, pmove->x, pmove->y, FALSE, FALSE); + handle_unit_move_request(punit, pmove->x, pmove->y, FALSE, FALSE, + pmove->dry_run,pmove->report_result); + } + else if(pmove->dry_run) + { + send_result(pplayer,R_ID_INVALID_OR_NOT_OWNER); } } @@ -680,7 +688,8 @@ int old_moves = punit->moves_left; int full_moves = unit_move_rate (punit); punit->moves_left = full_moves; - if (handle_unit_move_request(punit, def_x, def_y, FALSE, FALSE)) { + if (handle_unit_move_request(punit, def_x, def_y, FALSE, + FALSE, FALSE, FALSE)) { punit->moves_left = old_moves - (full_moves - punit->moves_left); if (punit->moves_left < 0) { punit->moves_left = 0; @@ -823,9 +832,10 @@ } /************************************************************************** -Return 1 if unit is alive, and 0 if it was killed +Return 1 if unit is alive, and 0 if it was killed. +If dry_run is true return 1 means is alive, and 0 may-get-killed. **************************************************************************/ -int handle_unit_enter_hut(struct unit *punit) +int handle_unit_enter_hut(struct unit *punit, int dry_run) { struct player *pplayer = unit_owner(punit); int ok = 1; @@ -834,16 +844,23 @@ return ok; } + if(!dry_run) + { map_get_tile(punit->x, punit->y)->special^=S_HUT; send_tile_info(0, punit->x, punit->y); + } if (game.rgame.hut_overflight==OVERFLIGHT_FRIGHTEN && is_air_unit(punit)) { + if(!dry_run) notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT, _("Game: Your overflight frightens the tribe;" " they scatter in terror.")); return ok; } + if(dry_run) + return 0; + switch (myrand(12)) { case 0: hut_get_gold(punit, 25); @@ -882,9 +899,13 @@ 'move_diplomat_city' is another special case which should normally be FALSE. If TRUE, try to move diplomat (or spy) into city (should be allied) instead of telling client to popup diplomat/spy dialog. + + If dry_run is true no changes will be made. A result packet will be + send back in every case. **************************************************************************/ int handle_unit_move_request(struct unit *punit, int dest_x, int dest_y, - int igzoc, int move_diplomat_city) + int igzoc, int move_diplomat_city, int dry_run, + int report_result) { struct player *pplayer = unit_owner(punit); struct tile *pdesttile = map_get_tile(dest_x, dest_y); @@ -894,15 +915,25 @@ /* barbarians shouldn't enter huts */ if (is_barbarian(pplayer) && pdesttile->special&S_HUT) { + if(report_result) + send_result(pplayer,R_BARBARIANS_ENTER_HUT); return 0; } /* this occurs often during lag, and to the AI due to some quirks -- Syela */ if (same_pos(punit->x, punit->y, dest_x, dest_y)) + { + if(report_result) + send_result(pplayer,R_SAME_POSITION); return 0; + } - if (do_airline(punit, dest_x, dest_y)) + if (do_airline(punit, dest_x, dest_y,dry_run)) + { + if(report_result) + send_result(pplayer,R_OK); return 1; + } if (unit_flag(punit->type, F_CARAVAN) && pcity @@ -913,7 +944,8 @@ req.unit_id = punit->id; req.city_id = pcity->id; req.name[0] = '\0'; - return handle_unit_establish_trade(pplayer, &req); + return handle_unit_establish_trade(pplayer, &req, + dry_run, report_result); } /* Pop up a diplomat action dialog in the client. If the AI has used @@ -930,6 +962,16 @@ || !move_diplomat_city)) { struct packet_diplomat_action packet; if (punit->activity == ACTIVITY_GOTO && pplayer->ai.control) + { + if(report_result) + send_result(pplayer,R_AI_DIPLOMAT_ON_GOTO); + return 0; + } + + if(report_result) + send_result(pplayer,R_DEFERRED_DIPLOMAT_ACTION); + + if(dry_run) return 0; /* If we didn't send_unit_info the client would sometimes think that @@ -959,12 +1001,16 @@ 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.")); + if(report_result) + send_result(pplayer,R_CANT_ATTACK); return 0; } if (punit->moves_left<=0) { notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT, _("Game: This unit has no moves left.")); + if(report_result) + send_result(pplayer,R_ZERO_MOVES_LEFT); return 0; } @@ -975,6 +1021,9 @@ unit_owner(pdefender)->name, pcity->name, city_owner(pcity)->name); + if(report_result) + send_result(pplayer,R_CANT_ATTACK_ALLIED_CITY); + return 0; } @@ -982,6 +1031,9 @@ if (pplayer->ai.control && punit->activity == ACTIVITY_GOTO) { notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT, _("Game: Aborting GOTO for AI attack procedures.")); + if(report_result) + send_result(pplayer,R_AI_GOTO); + return 0; } @@ -990,6 +1042,9 @@ notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT, _("Game: %s aborted GOTO as there are units in the way."), unit_types[punit->type].name); + if(report_result) + send_result(pplayer,R_ABORTING_GOTO); + return 0; } @@ -1018,10 +1073,18 @@ unit_name(punit->type)); notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT, message); + if(report_result) + send_result(pplayer,R_CANT_ATTACK_NO_ATTACK); + return 0; } + if(report_result) + send_result(pplayer,R_OK); + + if(!dry_run) handle_unit_attack_request(punit, pdefender); + return 1; } /* End attack case */ @@ -1032,10 +1095,12 @@ notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT, _("Game: No war declared against %s, cannot attack."), game.players[pdefender->owner].name); - return 0; - } + if(report_result) + send_result(pplayer,R_CANT_ATTACK_NOT_ALLIED_AND_NOT_AN_ENEMY); + return 0; + } { struct unit *bodyguard; @@ -1046,6 +1111,10 @@ notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT, _("Game: %s doesn't want to leave its bodyguard."), unit_types[punit->type].name); + + if(report_result) + send_result(pplayer,R_AI_BODYGUARD); + return 0; } } @@ -1059,6 +1128,10 @@ notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT, _("Game: %s ending move early to stay out of trouble."), unit_types[punit->type].name); + + if(report_result) + send_result(pplayer,R_AI_SOME_CASE); + return 0; } @@ -1069,6 +1142,10 @@ notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT, _("Game: Only ground troops can take over " "a city.")); + + if(report_result) + send_result(pplayer,R_CANT_CAPTURE_CITY); + return 0; } @@ -1077,13 +1154,18 @@ _("Game: No war declared against %s, cannot take " "over city."), game.players[pcity->owner].name); + + if(report_result) + send_result(pplayer,R_CANT_CAPTURE_CITY_NOT_AN_ENEMY); + return 0; } } /******* ok now move the unit *******/ - if(can_unit_move_to_tile(punit, dest_x, dest_y, igzoc) && - try_move_unit(punit, dest_x, dest_y)) { + if(can_unit_move_to_tile(punit, dest_x, dest_y, igzoc, + dry_run, report_result) && + try_move_unit(punit, dest_x, dest_y, dry_run, report_result)) { int src_x = punit->x; int src_y = punit->y; int move_cost = map_move_cost(punit, dest_x, dest_y); @@ -1091,10 +1173,22 @@ int take_from_land = punit->activity == ACTIVITY_IDLE; int survived; - survived = move_unit(punit, dest_x, dest_y, 1, take_from_land, move_cost); - if (!survived) + survived = move_unit(punit, dest_x, dest_y, 1, + take_from_land, move_cost, FALSE); + if(!survived) + { + if(report_result) + { + if(dry_run) + send_result(pplayer,R_MAY_KILLED_BY_BARBARIANS); + else + send_result(pplayer,R_KILLED_BY_BARBARIANS); + } return 1; + } + if(!dry_run) + { /* bodyguard code */ if(pplayer->ai.control && punit->ai.bodyguard > 0) { struct unit *bodyguard = unit_list_find(&psrctile->units, punit->ai.bodyguard); @@ -1104,15 +1198,20 @@ ACTIVITY_FORTIFIED and the unit has no chance of moving anyway */ handle_unit_activity_request(bodyguard, ACTIVITY_IDLE); success = handle_unit_move_request(bodyguard, - dest_x, dest_y, igzoc, FALSE); + dest_x, dest_y, igzoc, + FALSE, FALSE, FALSE); freelog(LOG_DEBUG, "Dragging %s from (%d,%d)->(%d,%d) (Success=%d)", unit_types[bodyguard->type].name, src_x, src_y, dest_x, dest_y, success); handle_unit_activity_request(bodyguard, ACTIVITY_FORTIFYING); } } + } /* !dry_run */ + if(report_result) + send_result(pplayer,R_OK); return 1; } else { + /* the result is already sent */ return 0; } } @@ -1138,7 +1237,8 @@ return; if (!(same_pos(punit->x, punit->y, pcity_dest->x, pcity_dest->y) - || try_move_unit(punit, pcity_dest->x, pcity_dest->y))) + || try_move_unit(punit, pcity_dest->x, pcity_dest->y, + FALSE, FALSE))) return; /* we're there! */ @@ -1166,27 +1266,56 @@ ... **************************************************************************/ int handle_unit_establish_trade(struct player *pplayer, - struct packet_unit_request *req) + struct packet_unit_request *req, + int dry_run, int report_result) { struct unit *punit; struct city *pcity_homecity, *pcity_dest; int revenue; punit = player_find_unit_by_id(pplayer, req->unit_id); - if (!punit || !unit_flag(punit->type, F_CARAVAN)) + if (!punit) + { + if(report_result) + send_result(pplayer, R_ID_INVALID_OR_NOT_OWNER); return 0; + } + + if(!unit_flag(punit->type, F_CARAVAN)) + { + if(report_result) + send_result(pplayer, R_NOT_A_CARAVAN); + return 0; + } pcity_homecity=player_find_city_by_id(pplayer, punit->homecity); pcity_dest=find_city_by_id(req->city_id); if(!pcity_homecity || !pcity_dest) + { + if(report_result) + send_result(pplayer,R_CITY_NOT_FOUND); + return 0; + } if (!is_tiles_adjacent(punit->x, punit->y, pcity_dest->x, pcity_dest->y)) + { + if(report_result) + send_result(pplayer,R_UNIT_TO_FAR); + return 0; + } if (!(same_pos(punit->x, punit->y, pcity_dest->x, pcity_dest->y) - || try_move_unit(punit, pcity_dest->x, pcity_dest->y))) + || try_move_unit(punit, pcity_dest->x, pcity_dest->y, dry_run, + report_result))) + { + + if(report_result) + send_result(pplayer,R_CANT_MOVE_UNIT); + return 0; + } if (!can_establish_trade_route(pcity_homecity, pcity_dest)) { int i; @@ -1199,6 +1328,10 @@ notify_player_ex(pplayer, pcity_dest->x, pcity_dest->y, E_NOEVENT, _(" A traderoute already exists between %s and %s!"), pcity_homecity->name, pcity_dest->name); + + if(report_result) + send_result(pplayer,R_TRADEROUTE_ALREADY_EST); + return 0; } } @@ -1206,17 +1339,34 @@ notify_player_ex(pplayer, pcity_dest->x, pcity_dest->y, E_NOEVENT, _(" The city of %s already has 4 trade routes!"), pcity_homecity->name); + + if(report_result) + send_result(pplayer,R_MAX_TRADEROUTES); + return 0; } if (city_num_trade_routes(pcity_dest)==4) { notify_player_ex(pplayer, pcity_dest->x, pcity_dest->y, E_NOEVENT, _(" The city of %s already has 4 trade routes!"), pcity_dest->name); + + if(report_result) + send_result(pplayer,R_MAX_TRADEROUTES); + return 0; } + + if(report_result) + send_result(pplayer,R_CANT_EST_TRADEROUTE); + return 0; } + if(report_result) + send_result(pplayer,R_OK); + + if(!dry_run) + { revenue = establish_trade_route(pcity_homecity, pcity_dest); conn_list_do_buffer(&pplayer->connections); notify_player_ex(pplayer, pcity_dest->x, pcity_dest->y, E_NOEVENT, @@ -1233,6 +1383,7 @@ send_city_info(pplayer, pcity_homecity); send_city_info(city_owner(pcity_dest), pcity_dest); conn_list_do_unbuffer(&pplayer->connections); + } /* !dry_run */ return 1; } diff -udarbB -X freeciv/diff_ignore freeciv/server/unithand.h freeciv.mod/server/unithand.h --- freeciv/server/unithand.h Tue Jan 9 00:44:38 2001 +++ freeciv.mod/server/unithand.h Sat Jan 13 00:51:31 2001 @@ -36,13 +36,15 @@ void handle_unit_build_city(struct player *pplayer, struct packet_unit_request *req); void handle_unit_info(struct player *pplayer, struct packet_unit_info *pinfo); -int handle_unit_enter_hut(struct unit *punit); +int handle_unit_enter_hut(struct unit *punit, int dry_run); int handle_unit_move_request(struct unit *punit, int dest_x, int dest_y, - int igzoc, int move_diplomat_city); + int igzoc, int move_diplomat_city, + int dry_run, int report_result); void handle_unit_help_build_wonder(struct player *pplayer, struct packet_unit_request *req); int handle_unit_establish_trade(struct player *pplayer, - struct packet_unit_request *req); + struct packet_unit_request *req, + int dry_run, int report_result); void handle_unit_enter_city(struct unit *punit, struct city *pcity); void handle_unit_auto_request(struct player *pplayer, struct packet_unit_request *req); diff -udarbB -X freeciv/diff_ignore freeciv/server/unittools.c freeciv.mod/server/unittools.c --- freeciv/server/unittools.c Wed Jan 10 17:52:57 2001 +++ freeciv.mod/server/unittools.c Sat Jan 13 00:51:32 2001 @@ -33,6 +33,7 @@ #include "shared.h" #include "support.h" #include "unit.h" +#include "result.h" #include "barbarian.h" #include "cityhand.h" @@ -621,7 +622,8 @@ 9) there is not a peaceful but un-allied city on the target tile 10) there is no non-allied unit blocking (zoc) [or igzoc is true] **************************************************************************/ -int can_unit_move_to_tile(struct unit *punit, int dest_x, int dest_y, int igzoc) +int can_unit_move_to_tile(struct unit *punit, int dest_x, int dest_y, + int igzoc, int dry_run, int report_result) { struct tile *pfromtile,*ptotile; int zoc; @@ -634,28 +636,54 @@ && punit->activity!=ACTIVITY_GOTO && punit->activity!=ACTIVITY_PATROL && !punit->connecting) + { + if(report_result) + send_result(unit_owner(punit),R_BAD_ACTIVITY); + return 0; + } /* 2) */ if (dest_x<0 || dest_x>=map.xsize || dest_y<0 || dest_y>=map.ysize) + { + + if(report_result) + send_result(unit_owner(punit),R_BAD_DESTINATION); + return 0; + } /* 3) */ if (!is_tiles_adjacent(src_x, src_y, dest_x, dest_y)) + { + if(report_result) + send_result(unit_owner(punit),R_DESTINATION_NOT_ADJACENT); + return 0; + } pfromtile = map_get_tile(src_x, src_y); ptotile = map_get_tile(dest_x, dest_y); /* 4) */ if (is_non_allied_unit_tile(ptotile, punit->owner)) + { + if(report_result) + send_result(unit_owner(punit),R_NON_ALLIED_UNITS_BLOCKING); + return 0; + } if (is_ground_unit(punit)) { /* 5) */ if (ptotile->terrain==T_OCEAN && ground_unit_transporter_capacity(dest_x, dest_y, punit->owner) <= 0) + { + if(report_result) + send_result(unit_owner(punit),R_NO_TRANSPORTER_CAPACITY); + return 0; + } /* Moving from ocean */ if (pfromtile->terrain==T_OCEAN) { @@ -672,6 +700,10 @@ notify_player_ex(unit_owner(punit), src_x, src_y, E_NOEVENT, _("Game: Cannot attack from sea.")); } + + if(report_result) + send_result(unit_owner(punit),R_GROUND_UNIT_ATTACKING_FROM_SEA); + return 0; } } @@ -680,14 +712,23 @@ if (ptotile->terrain!=T_OCEAN && ptotile->terrain!=T_UNKNOWN && !is_allied_city_tile(ptotile, punit->owner)) + { + if(report_result) + send_result(unit_owner(punit),R_BAD_DESTINATION_FOR_SHIP); + return 0; } + } /* 8) */ if (is_non_attack_unit_tile(ptotile, punit->owner)) { notify_player_ex(unit_owner(punit), src_x, src_y, E_NOEVENT, _("Game: Cannot attack unless you declare war first.")); + + if(report_result) + send_result(unit_owner(punit),R_CANT_ATTACK_NON_AN_ENEMY); + return 0; } @@ -697,6 +738,10 @@ notify_player_ex(unit_owner(punit), src_x, src_y, E_NOEVENT, _("Game: Cannot attack unless you declare war first.")); + + if(report_result) + send_result(unit_owner(punit),R_CANT_ATTACK_NON_AN_ENEMY); + return 0; } @@ -706,6 +751,10 @@ notify_player_ex(unit_owner(punit), src_x, src_y, E_NOEVENT, _("Game: %s can only move into your own zone of control."), unit_types[punit->type].name); + + if(report_result) + send_result(unit_owner(punit),R_ZOC); + } return zoc; @@ -1398,7 +1447,7 @@ _("Game: Moved your %s due to changing" " land to sea at (%d, %d)."), unit_name(punit2->type), punit2->x, punit2->y); - move_unit(punit2, x, y, 1, 0, 0); + move_unit(punit2, x, y, 1, 0, 0, FALSE); if (punit2->activity == ACTIVITY_SENTRY) handle_unit_activity_request(punit2, ACTIVITY_IDLE); goto START; @@ -1423,7 +1472,7 @@ _("Game: Embarked your %s due to changing" " land to sea at (%d, %d)."), unit_name(punit2->type), punit2->x, punit2->y); - move_unit(punit2, x, y, 1, 0, 0); + move_unit(punit2, x, y, 1, 0, 0, FALSE); if (punit2->activity == ACTIVITY_SENTRY) handle_unit_activity_request(punit2, ACTIVITY_IDLE); goto START; @@ -1468,7 +1517,7 @@ _("Game: Moved your %s due to changing" " sea to land at (%d, %d)."), unit_name(punit2->type), punit2->x, punit2->y); - move_unit(punit2, x, y, 1, 1, 0); + move_unit(punit2, x, y, 1, 1, 0, FALSE); if (punit2->activity == ACTIVITY_SENTRY) handle_unit_activity_request(punit2, ACTIVITY_IDLE); goto START; @@ -1493,7 +1542,7 @@ _("Game: Docked your %s due to changing" " sea to land at (%d, %d)."), unit_name(punit2->type), punit2->x, punit2->y); - move_unit(punit2, x, y, 1, 1, 0); + move_unit(punit2, x, y, 1, 1, 0, FALSE); if (punit2->activity == ACTIVITY_SENTRY) handle_unit_activity_request(punit2, ACTIVITY_IDLE); goto START; @@ -1778,7 +1827,7 @@ if (move_cost == -1) move_cost = punit->moves_left; - return move_unit(punit, dest_x, dest_y, 0, 0, move_cost); + return move_unit(punit, dest_x, dest_y, 0, 0, move_cost, FALSE); } return 0; } @@ -2428,21 +2477,43 @@ 2) or have it's moves set to 0 a unit can always move atleast once **************************************************************************/ -int try_move_unit(struct unit *punit, int dest_x, int dest_y) +int try_move_unit(struct unit *punit, int dest_x, int dest_y, int dry_run, + int report_result) { - if (myrand(1+map_move_cost(punit, dest_x, dest_y))>punit->moves_left && - punit->moves_leftmoves_left >= unit_move_rate(punit)) + return punit->moves_left; + + /* unit has enough moves left */ + if(punit->moves_left >=cost) + return punit->moves_left; + + /* now we roll the dice */ + + if (myrand(1+cost) <= punit->moves_left) + /* success */ + return punit->moves_left; + else + { + /* failed */ + if(!dry_run) + { punit->moves_left=0; send_unit_info(&game.players[punit->owner], punit); } - return punit->moves_left; + if(report_result) + send_result(unit_owner(punit),R_MAY_NOT_ENOUGH_MOVES_LEFT); + return 0; + } } /************************************************************************** go by airline, if both cities have an airport and neither has been used this turn the unit will be transported by it and have it's moves set to 0 **************************************************************************/ -int do_airline(struct unit *punit, int dest_x, int dest_y) +int do_airline(struct unit *punit, int dest_x, int dest_y, int dry_run) { struct city *city1, *city2; int src_x = punit->x; @@ -2454,6 +2525,9 @@ return 0; if (!unit_can_airlift_to(punit, city2)) return 0; + + if(!dry_run) + { city1->airlift=0; city2->airlift=0; @@ -2461,10 +2535,11 @@ _("Game: %s transported succesfully."), unit_name(punit->type)); - move_unit(punit, dest_x, dest_y, 0, 0, punit->moves_left); + move_unit(punit, dest_x, dest_y, 0, 0, punit->moves_left, dry_run); send_city_info(city_owner(city1), city1); send_city_info(city_owner(city2), city2); + } return 1; } @@ -2523,7 +2598,7 @@ { int move_cost = get_unit_type(punit->type)->paratroopers_mr_sub; punit->paradropped = 1; - return move_unit(punit, dest_x, dest_y, 0, 0, move_cost); + return move_unit(punit, dest_x, dest_y, 0, 0, move_cost, FALSE); } } @@ -2957,7 +3032,8 @@ Note that the src and dest need not be adjacent. **************************************************************************/ int move_unit(struct unit *punit, const int dest_x, const int dest_y, - int transport_units, int take_from_land, int move_cost) + int transport_units, int take_from_land, int move_cost, + int dry_run) { int src_x = punit->x; int src_y = punit->y; @@ -2966,6 +3042,8 @@ struct tile *psrctile = map_get_tile(src_x, src_y); struct tile *pdesttile = map_get_tile(dest_x, dest_y); + if(!dry_run) + { conn_list_do_buffer(&pplayer->connections); if (punit->ai.ferryboat) { @@ -3054,9 +3132,10 @@ handle_unit_move_consequences(punit, src_x, src_y, dest_x, dest_y); conn_list_do_unbuffer(&pplayer->connections); + } /* !dry_run */ if (map_get_tile(dest_x, dest_y)->special&S_HUT) - return handle_unit_enter_hut(punit); + return handle_unit_enter_hut(punit,dry_run); else return 1; } @@ -3095,7 +3174,7 @@ if (is_tiles_adjacent(punit->x, punit->y, x, y)) { int last_tile = (index+1)%pgr->length == pgr->last_index; freelog(LOG_DEBUG, "handling\n"); - res = handle_unit_move_request(punit, x, y, 0, !last_tile); + res = handle_unit_move_request(punit, x, y, 0, !last_tile, FALSE, FALSE); if (!player_find_unit_by_id(pplayer, unitid)) return; if (!res && punit->moves_left) { @@ -3126,4 +3205,12 @@ } } } /* end while*/ +} + +void send_result(struct player *dest, enum result_t result) +{ + struct packet_generic_integer req; + + req.value=result; + send_packet_generic_integer(dest->current_conn, PACKET_RESULT, &req); } diff -udarbB -X freeciv/diff_ignore freeciv/server/unittools.h freeciv.mod/server/unittools.h --- freeciv/server/unittools.h Tue Jan 9 00:44:38 2001 +++ freeciv.mod/server/unittools.h Sat Jan 13 00:51:32 2001 @@ -13,6 +13,8 @@ #ifndef FC__UNITTOOLS_H #define FC__UNITTOOLS_H +#include "result.h" + struct city; struct player; struct unit; @@ -47,8 +49,8 @@ int zoc_ok_move_gen(struct unit *punit, int x1, int y1, int x2, int y2); int zoc_ok_move(struct unit *punit,int x, int y); int unit_really_ignores_zoc(struct unit *punit); -int can_unit_move_to_tile(struct unit *punit, int dest_x, int dest_y, int igzoc); - +int can_unit_move_to_tile(struct unit *punit, int dest_x, int dest_y, + int igzoc, int dry_run, int report_result); /* turn update related */ void player_restore_units(struct player *pplayer); @@ -90,16 +92,18 @@ void send_unit_info_to_onlookers(struct conn_list *dest, struct unit *punit, int x, int y, int carried, int select_it); void send_all_known_units(struct conn_list *dest); - +void send_result(struct player *dest, enum result_t result); /* doing a unit activity */ void do_nuclear_explosion(int x, int y); -int try_move_unit(struct unit *punit, int dest_x, int dest_y); -int do_airline(struct unit *punit, int dest_x, int dest_y); +int try_move_unit(struct unit *punit, int dest_x, int dest_y, + int dry_run, int report_result); +int do_airline(struct unit *punit, int dest_x, int dest_y, int dry_run); int do_paradrop(struct unit *punit, int dest_x, int dest_y); void assign_units_to_transporter(struct unit *ptrans, int take_from_land); int move_unit(struct unit *punit, const int dest_x, const int dest_y, - int transport_units, int take_from_land, int move_cost); + int transport_units, int take_from_land, int move_cost, + int dry_run); void goto_route_execute(struct unit *punit); #endif /* FC__UNITTOOLS_H */