Index: common/unit.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v retrieving revision 1.25 diff -u -r1.25 unit.c --- unit.c 1998/10/20 12:32:42 1.25 +++ unit.c 1998/10/28 02:53:38 @@ -158,8 +158,10 @@ { struct city *pcity=map_get_city(destx, desty); struct tile *ptile=map_get_tile(destx, desty); + int move_cost = tile_move_cost(pdiplomat,pdiplomat->x,pdiplomat->y, destx, desty); - if(is_tiles_adjacent(pdiplomat->x, pdiplomat->y, destx, desty)) { + if(is_tiles_adjacent(pdiplomat->x, pdiplomat->y, destx, desty) && pdiplomat->moves_left >= move_cost) { + if(pcity) { if(pcity->owner!=pdiplomat->owner) { if(action==DIPLOMAT_SABOTAGE) Index: server/citytools.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v retrieving revision 1.21 diff -u -r1.21 citytools.c --- citytools.c 1998/10/25 05:24:49 1.21 +++ citytools.c 1998/10/28 02:53:39 @@ -605,8 +605,8 @@ /* Transfer units in the city to the new owner */ unit_list_iterate(map_get_tile(x, y)->units, vunit) { - create_unit(pplayer, x, y, vunit->type, vunit->veteran, - pcity->id, vunit->moves_left); + create_unit_full(pplayer, x, y, vunit->type, vunit->veteran, + pcity->id, vunit->moves_left, vunit->hp); wipe_unit(0, vunit); } unit_list_iterate_end; @@ -617,8 +617,9 @@ if(new_home_city) { /* unit is in another city: make that the new homecity */ - create_unit(pvictim, vunit->x, vunit->y, vunit->type, - vunit->veteran, new_home_city->id, vunit->moves_left); + create_unit_full(pvictim, vunit->x, vunit->y, vunit->type, + vunit->veteran, new_home_city->id, vunit->moves_left, + vunit->hp); } /* unit isn't in a city - Civ2 deletes it - seems like a good idea to Index: server/unitfunc.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/unitfunc.c,v retrieving revision 1.55 diff -u -r1.55 unitfunc.c --- unitfunc.c 1998/10/27 13:50:43 1.55 +++ unitfunc.c 1998/10/28 02:53:41 @@ -164,9 +164,9 @@ notify_player_ex(pplayer, pvictim->x, pvictim->y, E_NOEVENT, "Game: Succeeded in bribing the enemy unit."); - create_unit(pplayer, pvictim->x, pvictim->y, + create_unit_full(pplayer, pvictim->x, pvictim->y, pvictim->type, pvictim->veteran, pdiplomat->homecity, - pvictim->moves_left); + pvictim->moves_left, pvictim->hp); light_square(pplayer, pvictim->x, pvictim->y, get_unit_type(pvictim->type)->vision_range); wipe_unit(0, pvictim); @@ -372,8 +372,12 @@ notify_player_ex(pplayer, pcity->x, pcity->y, E_NOEVENT, "Game: Your spy has successfully completed her mission and returned unharmed to %s.", spyhome->name); + /* being teleported costs 1 move */ + if(pdiplomat->moves_left > 3) pdiplomat->moves_left -= 3; + else + pdiplomat->moves_left = 0; create_unit(pplayer, spyhome->x, spyhome->y, pdiplomat->type, 1, spyhome->id, pdiplomat->moves_left); @@ -996,8 +1000,17 @@ TODO: Maybe this procedure should refresh its homecity? so it'll show up immediately on the clients? (refresh_city + send_city_info) **************************************************************************/ -void create_unit(struct player *pplayer, int x, int y, enum unit_type_id type, - int make_veteran, int homecity_id, int moves_left) + +/* This is a wrapper */ + +void create_unit(struct player *pplayer, int x, int y, enum unit_type_id type, int make_veteran, int homecity_id, int moves_left){ + create_unit_full(pplayer,x,y,type,make_veteran,homecity_id,moves_left,-1); +} + +/* This is the full call. We don't want to have to change all other calls to + this function to ensure the hp are set */ + +void create_unit_full(struct player *pplayer, int x, int y, enum unit_type_id type, int make_veteran, int homecity_id, int moves_left, int hp_left) { struct unit *punit; struct city *pcity; @@ -1015,7 +1028,11 @@ pcity=game_find_city_by_id(homecity_id); punit->veteran=make_veteran; punit->homecity=homecity_id; - punit->hp=get_unit_type(punit->type)->hp; + + if(hp_left == -1) + punit->hp=get_unit_type(punit->type)->hp; + else + punit->hp = hp_left; punit->activity=ACTIVITY_IDLE; punit->activity_count=0; punit->upkeep=0; Index: server/unitfunc.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/unitfunc.h,v retrieving revision 1.10 diff -u -r1.10 unitfunc.h --- unitfunc.h 1998/08/19 23:17:10 1.10 +++ unitfunc.h 1998/10/28 02:53:41 @@ -42,6 +42,9 @@ void create_unit(struct player *pplayer, int x, int y, enum unit_type_id type, int make_veteran, int homecity_id, int moves_left); +void create_unit_full(struct player *pplayer, int x, int y, enum unit_type_id + type, int make_veteran, int homecity_id, int moves_left + , int hp); void send_remove_unit(struct player *pplayer, int unit_id); void wipe_unit(struct player *dest, struct unit *punit); void kill_unit(struct unit *pkiller, struct unit *punit); Index: server/unithand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v retrieving revision 1.39 diff -u -r1.39 unithand.c --- unithand.c 1998/10/27 13:50:44 1.39 +++ unithand.c 1998/10/28 02:53:42 @@ -188,36 +188,49 @@ move_cost = tile_move_cost(pdiplomat,pdiplomat->x,pdiplomat->y, x, y); if(pdiplomat && pdiplomat->moves_left >= move_cost) { - pdiplomat->moves_left -= move_cost; - send_unit_info(pplayer, pdiplomat, 0); + switch(packet->action_type) { case DIPLOMAT_BRIBE: if(pvictim && diplomat_can_do_action(pdiplomat, DIPLOMAT_BRIBE, - pvictim->x, pvictim->y)) + pvictim->x, pvictim->y)){ + pdiplomat->moves_left -= move_cost; + send_unit_info(pplayer, pdiplomat, 0); diplomat_bribe(pplayer, pdiplomat, pvictim); + } break; case SPY_SABOTAGE_UNIT: if(pvictim && diplomat_can_do_action(pdiplomat, SPY_SABOTAGE_UNIT, - pvictim->x, pvictim->y)) + pvictim->x, pvictim->y)){ + pdiplomat->moves_left -= move_cost; + send_unit_info(pplayer, pdiplomat, 0); spy_sabotage_unit(pplayer, pdiplomat, pvictim); + } break; case DIPLOMAT_SABOTAGE: if(pcity && diplomat_can_do_action(pdiplomat, DIPLOMAT_SABOTAGE, - pcity->x, pcity->y)) + pcity->x, pcity->y)){ + pdiplomat->moves_left -= move_cost; + send_unit_info(pplayer, pdiplomat, 0); diplomat_sabotage(pplayer, pdiplomat, pcity, packet->value); + } break; case SPY_POISON: if(pcity && diplomat_can_do_action(pdiplomat, SPY_POISON, - pcity->x, pcity->y)) + pcity->x, pcity->y)){ + pdiplomat->moves_left -= move_cost; + send_unit_info(pplayer, pdiplomat, 0); spy_poison(pplayer, pdiplomat, pcity); + } break; case DIPLOMAT_INVESTIGATE: /* Note: this is free (no movement cost) for spies */ if(pcity && diplomat_can_do_action(pdiplomat,DIPLOMAT_INVESTIGATE , - pcity->x, pcity->y)) + pcity->x, pcity->y)){ + send_unit_info(pplayer, pdiplomat, 0); diplomat_investigate(pplayer, pdiplomat, pcity); + } break; case DIPLOMAT_EMBASSY: if(pcity && diplomat_can_do_action(pdiplomat, DIPLOMAT_EMBASSY, @@ -248,12 +261,17 @@ break; case DIPLOMAT_INCITE: if(pcity && diplomat_can_do_action(pdiplomat, DIPLOMAT_INCITE, - pcity->x, pcity->y)) + pcity->x, pcity->y)){ + pdiplomat->moves_left -= move_cost; + send_unit_info(pplayer, pdiplomat, 0); diplomat_incite(pplayer, pdiplomat, pcity); + } break; case DIPLOMAT_STEAL: if(pcity && diplomat_can_do_action(pdiplomat, DIPLOMAT_STEAL, pcity->x, pcity->y)){ + pdiplomat->moves_left -= move_cost; + send_unit_info(pplayer, pdiplomat, 0); diplomat_get_tech(pplayer, pdiplomat, pcity, packet->value); } break; Index: server/unittools.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v retrieving revision 1.26 diff -u -r1.26 unittools.c --- unittools.c 1998/09/01 14:32:38 1.26 +++ unittools.c 1998/10/28 02:53:43 @@ -199,12 +199,16 @@ calculate how expensive it is to bribe the unit depends on distance to the capital, and government form settlers are half price + + Plus, the damage to the unit reduces the price. + **************************************************************************/ int unit_bribe_cost(struct unit *punit) { int cost; struct city *capital; int dist; + int default_hp = get_unit_type(punit->type)->hp; cost = (&game.players[punit->owner])->economic.gold+750; capital=find_palace(&game.players[punit->owner]); @@ -217,6 +221,15 @@ cost=(cost/(dist+2))*(get_unit_type(punit->type)->build_cost/10); if (unit_flag(punit->type, F_SETTLERS)) cost/=2; + + /* Cost now contains the basic bribe cost. We now reduce it by: + + cost = basecost/2 + basecost/2 * damage/hp + + */ + + cost = (int)((float)cost/(float)2 + ((float)punit->hp/(float)default_hp) * ((float)cost/(float)2)); + return cost; }