diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/freeciv_hackers_guide.txt do_something/freeciv_hackers_guide.txt --- freeciv/freeciv_hackers_guide.txt Thu Apr 27 14:49:14 2000 +++ do_something/freeciv_hackers_guide.txt Thu Apr 27 15:45:08 2000 @@ -254,8 +254,9 @@ and void map_unfog_city_area(struct city *pcity) that can be called for specific purposes like, say, moving a unit's sight -point when you move the unit. These all call fog_area and unfog_area in -turn. +points when you move the unit (this is handled as part of the +handle_unit_move_consequences function). These all call fog_area and +unfog_area in turn. [Beware of using map_adjust_y. If you have a 80x50 map and then iterate around the tile 40,49 you can get values like 40,50, which is not a diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/server/unitfunc.c do_something/server/unitfunc.c --- freeciv/server/unitfunc.c Thu Apr 27 15:42:42 2000 +++ do_something/server/unitfunc.c Thu Apr 27 19:14:21 2000 @@ -55,6 +55,8 @@ /****************************************************************************/ +static void wakeup_neighbor_sentries(struct player *pplayer, + int cent_x, int cent_y); static void diplomat_charge_movement (struct unit *pdiplomat, int x, int y); static int diplomat_success_vs_defender (struct unit *pdefender); static int diplomat_infiltrate_city (struct player *pplayer, struct player *cplayer, @@ -1176,6 +1178,31 @@ wipe_unit (0, pdiplomat); } +/***************************************************************** + Will wake up any neighboring enemy sentry units +*****************************************************************/ +static void wakeup_neighbor_sentries(struct player *pplayer, + int cent_x, int cent_y) +{ + int x,y; +/* struct unit *punit; The unit_list_iterate defines punit locally. -- Syela */ + + for (x = cent_x-1;x <= cent_x+1;x++) + for (y = cent_y-1;y <= cent_y+1;y++) + if ((x != cent_x)||(y != cent_y)) + { + unit_list_iterate(map_get_tile(x,y)->units, punit) { + if ((pplayer->player_no != punit->owner)&& + (punit->activity == ACTIVITY_SENTRY)) + { + set_unit_activity(punit, ACTIVITY_IDLE); + send_unit_info(0,punit); + } + } + unit_list_iterate_end; + } +} + /*************************************************************************** Return 1 if upgrading this unit could cause passengers to get stranded at sea, due to transport capacity changes @@ -2074,7 +2101,8 @@ unit_list_unlink(&map_get_tile(src_x, src_y)->units, punit); punit->x = x; punit->y = y; unit_list_insert(&map_get_tile(x, y)->units, punit); - teleport_unit_sight_points(src_x, src_y, x, y, punit); + + punit->moved = 1; connection_do_buffer(game.players[punit->owner].conn); send_unit_info(&game.players[punit->owner], punit); @@ -2083,10 +2111,9 @@ notify_player_ex(&game.players[punit->owner], punit->x, punit->y, E_NOEVENT, _("Game: %s transported succesfully."), unit_name(punit->type)); + handle_unit_move_consequences(punit, src_x, src_y, x, y, 1); connection_do_unbuffer(game.players[punit->owner].conn); - punit->moved=1; - return 1; } @@ -2142,40 +2169,24 @@ /* All ok */ { - struct city *start_city = map_get_city(punit->x, punit->y); - struct city *dest_city = map_get_city(x, y); - - /* unfog the squares the unit is entering */ - teleport_unit_sight_points(punit->x, punit->y, x, y, punit); - + int src_x = punit->x, src_y = punit->y; + int ok; unit_list_unlink(&map_get_tile(punit->x, punit->y)->units, punit); punit->x = x; punit->y = y; unit_list_insert(&map_get_tile(x, y)->units, punit); punit->moves_left -= get_unit_type(punit->type)->paratroopers_mr_sub; - if(punit->moves_left < 0) punit->moves_left = 0; + if (punit->moves_left < 0) + punit->moves_left = 0; punit->paradropped = 1; - send_unit_info(0, punit); - - if(start_city) { - send_city_info(pplayer, start_city); - } - - if(dest_city) { - handle_unit_enter_city(pplayer, dest_city); - send_city_info(city_owner(dest_city), dest_city); - } - punit->moved = 1; - if((map_get_tile(x, y)->special&S_HUT)) { - /* punit might get killed by horde of barbarians */ - if (! (handle_unit_enter_hut(punit)) ) - return 1; /* We died, but we did do the paradrop */ - } - } + send_unit_info(0, punit); + /* might be killed by barbarians in hut */ + ok = handle_unit_move_consequences(punit, src_x, src_y, x, y, 1); - return 1; + return ok; + } } /************************************************************************** @@ -2619,4 +2630,137 @@ } return (restr); +} + + +/************************************************************************** +... +**************************************************************************/ +void send_all_known_units(struct player *dest) +{ + int o,p; + for(p=0; punits,punit) + send_unit_info(pplayer, punit); + unit_list_iterate_end; + } +} + +/************************************************************************** +... +**************************************************************************/ +void upgrade_unit(struct unit *punit, Unit_Type_id to_unit) +{ + struct player *pplayer = &game.players[punit->owner]; + int range = get_unit_type(punit->type)->vision_range; + + if (punit->hp==get_unit_type(punit->type)->hp) { + punit->hp=get_unit_type(to_unit)->hp; + } + + connection_do_buffer(pplayer->conn); + punit->type = to_unit; + unfog_area(pplayer,punit->x,punit->y, get_unit_type(to_unit)->vision_range); + fog_area(pplayer,punit->x,punit->y,range); + send_unit_info(0, punit); + connection_do_unbuffer(pplayer->conn); +} + +/************************************************************************** +Does: 1) updates the units homecity and the city it enters/leaves (the + cities happiness varies). This also takes into account if the + unit enters/leaves a fortress. + 2) handles any huts at the units destination. + 3) awakes any sentried units on neightborin tiles +Returns: if the unit survived (it can die in the hut) + +send_unit_info should be called AFTER this function so that the little +angry faces on units gets updated. send_unit_info will detect + +FIXME: Sometimes it is not neccesary to send cities because the goverment + doesn't care if a unit is away or not. +**************************************************************************/ +int handle_unit_move_consequences(struct unit *punit, int src_x, int src_y, + int dest_x, int dest_y, int enter_hut) +{ + struct city *fromcity = map_get_city(src_x, src_y); + struct city *tocity = map_get_city(dest_x, dest_y); + struct city *homecity = NULL; + struct player *pplayer = get_player(punit->owner); + /* struct government *g = get_gov_pplayer(pplayer);*/ + int sentfrom = 0, sentto = 0, senthome = 0; + if (punit->homecity) + homecity = find_city_by_id(punit->homecity); + + teleport_unit_sight_points(src_x, src_y, dest_x, dest_y, punit); + wakeup_neighbor_sentries(pplayer, dest_x, dest_y); + + if (tocity) + handle_unit_enter_city(punit, tocity); + + /* We only do this for non-AI players to now make sure the AI turns + doesn't take too long. Perhaps we should make a special refresh_city + functions that only refreshed happiness. */ + if (!pplayer->ai.control) { + /* might have changed owners */ + tocity = map_get_city(dest_x, dest_y); + + if (tocity) { /* entering a city */ + if (tocity->owner == punit->owner) { + if (tocity != homecity) { + city_refresh(tocity); + send_city_info(pplayer, tocity); + } + } + + if (homecity) { + city_refresh(homecity); + send_city_info(pplayer, homecity); + send_unit_info(pplayer, punit); /* little angry face on unit */ + } + senthome = sentto = 1; + } + + if (fromcity && fromcity->owner == punit->owner) { /* leaving a city */ + if (!senthome && homecity) { + city_refresh(homecity); + send_city_info(pplayer, homecity); + } + if (fromcity != homecity && !sentfrom) { + city_refresh(fromcity); + send_city_info(pplayer, fromcity); + send_unit_info(pplayer, punit); /* little angry face on unit */ + } + senthome = sentfrom = 1; + } + + /* entering/leaving a fortress */ + if (map_get_tile(dest_x, dest_y)->special&S_FORTRESS + && homecity + && real_map_distance(homecity->x, homecity->y, dest_x, dest_y) <= 3 + && !senthome) { + city_refresh(homecity); + send_city_info(pplayer, homecity); + send_unit_info(pplayer, punit); /* little angry face on unit */ + } + + if (map_get_tile(src_x, src_y)->special&S_FORTRESS + && homecity + && real_map_distance(homecity->x, homecity->y, src_x, src_y) <= 3 + && !senthome) { + city_refresh(homecity); + send_city_info(pplayer, homecity); + send_unit_info(pplayer, punit); /* little angry face on unit */ + } + } + + /* punit might get killed by horde of barbarians */ + if(enter_hut && (map_get_tile(dest_x, dest_y)->special&S_HUT)) { + return handle_unit_enter_hut(punit); + } + return 1; } diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/server/unitfunc.h do_something/server/unitfunc.h --- freeciv/server/unitfunc.h Thu Apr 27 14:49:30 2000 +++ do_something/server/unitfunc.h Thu Apr 27 17:56:49 2000 @@ -72,6 +72,10 @@ void get_a_tech(struct player *pplayer, struct player *target); void place_partisans(struct city *pcity,int count); void make_partisans(struct city *pcity); +void send_all_known_units(struct player *dest); +void upgrade_unit(struct unit *punit, Unit_Type_id to_unit); +int handle_unit_move_consequences(struct unit *punit, int src_x, int src_y, + int dest_x, int dest_y, int enter_hut); char *get_location_str_in(struct player *pplayer, int x, int y, char *prefix); char *get_location_str_at(struct player *pplayer, int x, int y, char *prefix); diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/server/unithand.c do_something/server/unithand.c --- freeciv/server/unithand.c Thu Apr 27 14:49:30 2000 +++ do_something/server/unithand.c Thu Apr 27 19:20:51 2000 @@ -773,32 +773,6 @@ return ok; } - -/***************************************************************** - Will wake up any neighboring enemy sentry units -*****************************************************************/ -static void wakeup_neighbor_sentries(struct player *pplayer, - int cent_x, int cent_y) -{ - int x,y; -/* struct unit *punit; The unit_list_iterate defines punit locally. -- Syela */ - - for (x = cent_x-1;x <= cent_x+1;x++) - for (y = cent_y-1;y <= cent_y+1;y++) - if ((x != cent_x)||(y != cent_y)) - { - unit_list_iterate(map_get_tile(x,y)->units, punit) { - if ((pplayer->player_no != punit->owner)&& - (punit->activity == ACTIVITY_SENTRY)) - { - set_unit_activity(punit, ACTIVITY_IDLE); - send_unit_info(0,punit); - } - } - unit_list_iterate_end; - } -} - /************************************************************************** ... **************************************************************************/ @@ -839,15 +813,16 @@ return 0; } - if (same_pos(punit->x, punit->y, dest_x, dest_y)) return 0; -/* this occurs often during lag, and to the AI due to some quirks -- Syela */ + /* 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)) + return 0; - unit_id=punit->id; + unit_id = punit->id; if (do_airline(punit, dest_x, dest_y)) return 1; if (unit_flag(punit->type, F_CARAVAN) - && (pcity=map_get_city(dest_x, dest_y)) + && (pcity = map_get_city(dest_x, dest_y)) && (pcity->owner != punit->owner) && punit->homecity) { struct packet_unit_request req; @@ -868,7 +843,7 @@ return 0; } - pdefender=get_defender(pplayer, punit, dest_x, dest_y); + pdefender = get_defender(pplayer, punit, dest_x, dest_y); if(pdefender && pdefender->owner!=punit->owner) { if(can_unit_attack_tile(punit,dest_x , dest_y)) { @@ -949,15 +924,10 @@ if(!player_find_unit_by_id(pplayer, unit_id)) return 0; /* diplomat or caravan action killed unit */ + /******* ok now move the unit *******/ connection_do_buffer(pplayer->conn); - src_x=punit->x; - src_y=punit->y; - - /* show new land and update fog-of-war */ - teleport_unit_sight_points(src_x,src_y,dest_x,dest_y,punit); - - /* ok now move the unit */ + src_x = punit->x; src_y = punit->y; if (punit->ai.ferryboat) { ferryboat = unit_list_find(&map_get_tile(punit->x, punit->y)->units, @@ -970,72 +940,62 @@ } } /* just clearing that up */ - if((punit->activity == ACTIVITY_GOTO) && - get_defender(pplayer,punit,punit->goto_dest_x,punit->goto_dest_y) && + if ((punit->activity == ACTIVITY_GOTO) && + get_defender(pplayer, punit, punit->goto_dest_x, punit->goto_dest_y) && (map_get_tile(punit->x,punit->y)->terrain != T_OCEAN)) { /* we should not take units with us -- fisch */ transport_units = 0; } - unit_list_unlink(&map_get_tile(src_x, src_y)->units, punit); - if(get_transporter_capacity(punit) && transport_units) { - transporter_cargo_to_unitlist(punit, &cargolist); - - unit_list_iterate(cargolist, pcarried) { - pcarried->x=dest_x; - pcarried->y=dest_y; - send_unit_info_to_onlookers(0, pcarried,src_x,src_y); - teleport_unit_sight_points(src_x,src_y,dest_x,dest_y,pcarried); - } - unit_list_iterate_end; + if (get_transporter_capacity(punit) && transport_units) { + transporter_cargo_to_unitlist(punit, &cargolist); + + unit_list_iterate(cargolist, pcarried) { + pcarried->x=dest_x; + pcarried->y=dest_y; + send_unit_info_to_onlookers(0, pcarried,src_x,src_y); + handle_unit_move_consequences(pcarried, src_x, src_y, dest_x, dest_y, 0); + } + unit_list_iterate_end; } - - if((punit->moves_left-=map_move_cost(punit, dest_x, dest_y))<0) + + if ((punit->moves_left-=map_move_cost(punit, dest_x, dest_y))<0) punit->moves_left=0; - punit->x=dest_x; - punit->y=dest_y; + punit->x = dest_x; + punit->y = dest_y; /*set activity to sentry if boarding a ship*/ - if(is_ground_unit(punit) && - map_get_terrain(punit->x, punit->y) == T_OCEAN && - !(pplayer->ai.control)) { + if (is_ground_unit(punit) && + map_get_terrain(punit->x, punit->y) == T_OCEAN && + !(pplayer->ai.control)) { set_unit_activity(punit, ACTIVITY_SENTRY); } - send_unit_info_to_onlookers(0, punit, src_x, src_y); - unit_list_insert(&map_get_tile(dest_x, dest_y)->units, punit); - - if(get_transporter_capacity(punit) && transport_units) { + + if (get_transporter_capacity(punit) && transport_units) { transporter_cargo_move_to_tile(&cargolist, punit->x, punit->y); genlist_unlink_all(&cargolist.list); } - - /* ok entered new tile */ - - if(pcity) - handle_unit_enter_city(pplayer, pcity); - ok = 1; - if((map_get_tile(dest_x, dest_y)->special&S_HUT)) { - /* punit might get killed by horde of barbarians */ - ok = handle_unit_enter_hut(punit); - } - - wakeup_neighbor_sentries(pplayer,dest_x,dest_y); - + /***** ok entered new tile *****/ + + send_unit_info_to_onlookers(0, punit, src_x, src_y); + ok = handle_unit_move_consequences(punit, src_x, src_y, dest_x, dest_y, 1); + connection_do_unbuffer(pplayer->conn); - if (!ok) return 1; - + if (!ok) /* has it been killed? then exit here */ + return 1; + /* bodyguard code */ if(pplayer->ai.control && player_find_unit_by_id(pplayer, unit_id)) { if (punit->ai.bodyguard > 0) { bodyguard = unit_list_find(&(map_get_tile(src_x, src_y)->units), - punit->ai.bodyguard); + punit->ai.bodyguard); if (bodyguard) { int success; handle_unit_activity_request(bodyguard, ACTIVITY_IDLE); @@ -1179,17 +1139,18 @@ /************************************************************************** ... **************************************************************************/ -void handle_unit_enter_city(struct player *pplayer, struct city *pcity) +void handle_unit_enter_city(struct unit *punit, struct city *pcity) { int i, n, do_civil_war = 0; int coins; + struct player *pplayer = unit_owner(punit); struct player *cplayer; struct city *pnewcity; - if(pplayer->player_no==pcity->owner) + if (punit->owner==pcity->owner) return; - cplayer=city_owner(pcity); + cplayer = city_owner(pcity); /* If a capital is captured, then spark off a civil war - Kris Bubendorfer @@ -1406,48 +1367,25 @@ do_paradrop(pplayer,punit,req->x, req->y); } } + /************************************************************************** -... +We remove the unit and see if it's disapperance have affected the homecity +and the city it was in. **************************************************************************/ void server_remove_unit(struct unit *punit) { - remove_unit_sight_points(punit); - game_remove_unit(punit->id); -} + struct city *pcity = map_get_city(punit->x, punit->y); + struct city *phomecity = find_city_by_id(punit->homecity); -/************************************************************************** -... -**************************************************************************/ -void send_all_known_units(struct player *dest) -{ - int o,p; - for(p=0; punits,punit) - send_unit_info(pplayer, punit); - unit_list_iterate_end; - } -} - -/************************************************************************** -... -**************************************************************************/ -void upgrade_unit(struct unit *punit, Unit_Type_id to_unit) -{ - struct player *pplayer = &game.players[punit->owner]; - int range = get_unit_type(punit->type)->vision_range; + remove_unit_sight_points(punit); + game_remove_unit(punit->id); - if (punit->hp==get_unit_type(punit->type)->hp) { - punit->hp=get_unit_type(to_unit)->hp; + if (phomecity) { + city_refresh(phomecity); + send_city_info(get_player(phomecity->owner), phomecity); + } + if (pcity && pcity != phomecity) { + city_refresh(pcity); + send_city_info(get_player(pcity->owner), pcity); } - - connection_do_buffer(pplayer->conn); - punit->type = to_unit; - unfog_area(pplayer,punit->x,punit->y, get_unit_type(to_unit)->vision_range); - fog_area(pplayer,punit->x,punit->y,range); - send_unit_info(0, punit); - connection_do_unbuffer(pplayer->conn); } diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/server/unithand.h do_something/server/unithand.h --- freeciv/server/unithand.h Thu Apr 27 14:49:30 2000 +++ do_something/server/unithand.h Thu Apr 27 17:32:44 2000 @@ -46,7 +46,7 @@ struct packet_unit_request *req); int handle_unit_establish_trade(struct player *pplayer, struct packet_unit_request *req); -void handle_unit_enter_city(struct player *pplayer, struct city *pcity); +void handle_unit_enter_city(struct unit *punit, struct city *pcity); void handle_unit_auto_request(struct player *pplayer, struct packet_unit_request *req); void handle_unit_activity_request(struct unit *punit, @@ -63,8 +63,6 @@ void handle_move_unit(struct player *pplayer, struct packet_move_unit *pmove); void handle_incite_inq(struct player *pplayer, struct packet_generic_integer *packet); -void send_all_known_units(struct player *dest); -void upgrade_unit(struct unit *punit, Unit_Type_id to_unit); #endif /* FC__UNITHAND_H */ diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/server/unittools.c do_something/server/unittools.c --- freeciv/server/unittools.c Thu Apr 27 14:49:30 2000 +++ do_something/server/unittools.c Thu Apr 27 19:10:13 2000 @@ -710,7 +710,6 @@ { int src_x = punit->x,src_y = punit->y; if(pcity->owner == punit->owner){ - teleport_unit_sight_points(src_x, src_y, pcity->x, pcity->y, punit); unit_list_unlink(&map_get_tile(punit->x, punit->y)->units, punit); punit->x = pcity->x; punit->y = pcity->y; @@ -721,6 +720,7 @@ unit_list_insert(&map_get_tile(pcity->x, pcity->y)->units, punit); send_unit_info_to_onlookers(0, punit, src_x,src_y); + handle_unit_move_consequences(punit, src_x, src_y, pcity->x, pcity->y, 1); freelog(LOG_VERBOSE, "Teleported %s's %s from (%d, %d) to %s", get_player(punit->owner)->name, unit_name(punit->type),