diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/freeciv_hackers_guide.txt send_on_disband/freeciv_hackers_guide.txt --- freeciv/freeciv_hackers_guide.txt Tue Apr 11 16:28:54 2000 +++ send_on_disband/freeciv_hackers_guide.txt Tue Apr 11 21:30:30 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. +point 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 send_on_disband/server/unitfunc.c --- freeciv/server/unitfunc.c Tue Apr 11 19:24:45 2000 +++ send_on_disband/server/unitfunc.c Tue Apr 11 20:57:33 2000 @@ -1988,6 +1988,7 @@ int do_airline(struct unit *punit, int x, int y) { struct city *city1, *city2; + int src_x = punit->x, src_y = punit->y; if (!(city1=map_get_city(punit->x, punit->y))) return 0; @@ -2007,13 +2008,14 @@ send_unit_info(&game.players[punit->owner], punit); send_city_info(city_owner(city1), city1); send_city_info(city_owner(city2), city2); + handle_unit_move_consequences(punit, src_x, src_y, x, y); notify_player_ex(&game.players[punit->owner], punit->x, punit->y, E_NOEVENT, _("Game: %s transported succesfully."), unit_name(punit->type)); connection_do_unbuffer(game.players[punit->owner].conn); punit->moved=1; - + return 1; } @@ -2033,37 +2035,20 @@ if(!is_enemy_unit_tile(x,y,punit->owner)) { int range = get_unit_type(punit->type)->paratroopers_range; if(real_map_distance(punit->x, punit->y, x, y) <= range) { - struct city *start_city = map_get_city(punit->x, punit->y); - struct city *dest_city = map_get_city(x, y); - int ok=1; - - /* light the squares the unit is entering */ - teleport_unit_sight_points(punit->x, punit->y, x, y, punit); + int ok; + int src_x = punit->x, src_y = punit->y; 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); - ok = 1; - if((map_get_tile(x, y)->special&S_HUT)) { - /* punit might get killed by horde of barbarians */ - ok = handle_unit_enter_hut(punit); - } + ok = handle_unit_move_consequences(punit, src_x, src_y, x, y); if(ok) { punit->moves_left -= get_unit_type(punit->type)->paratroopers_mr_sub; 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; } diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/server/unithand.c send_on_disband/server/unithand.c --- freeciv/server/unithand.c Tue Apr 11 16:28:59 2000 +++ send_on_disband/server/unithand.c Tue Apr 11 22:58:48 2000 @@ -816,15 +816,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; @@ -834,7 +835,7 @@ return handle_unit_establish_trade(pplayer, &req); } - 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)) { @@ -920,9 +921,6 @@ 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 */ if (punit->ai.ferryboat) { @@ -952,7 +950,7 @@ 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); + handle_unit_move_consequences(pcarried, src_x, src_y, dest_x, dest_y); } unit_list_iterate_end; } @@ -979,23 +977,14 @@ genlist_unlink_all(&cargolist.list); } - /* ok entered new tile */ - - if(pcity) - handle_unit_enter_city(pplayer, pcity); + ok = handle_unit_move_consequences(punit, src_x, src_y, dest_x, dest_y); + if (!ok) /* has it been killed? then exit here */ + return 1; - 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 */ connection_do_unbuffer(pplayer->conn); - if (!ok) return 1; - /* bodyguard code */ if(pplayer->ai.control && unit_list_find(&pplayer->units, unit_id)) { @@ -1145,14 +1134,15 @@ /************************************************************************** ... **************************************************************************/ -void handle_unit_enter_city(struct player *pplayer, struct city *pcity) +void handle_unit_enter_city(struct unit *punit, struct city *pcity) { + struct player *pplayer = get_player(punit->owner); int i, n, do_civil_war = 0; int coins; struct player *cplayer; struct city *pnewcity; - if(pplayer->player_no==pcity->owner) + if (pplayer->player_no == pcity->owner) return; cplayer=city_owner(pcity); @@ -1357,12 +1347,19 @@ } } /************************************************************************** -... +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) { + struct city *pcity = map_get_city(punit->x, punit->y); + struct city *homecity = find_city_by_id(punit->homecity); remove_unit_sight_points(punit); game_remove_unit(punit->id); + if (pcity && pcity != homecity) { + city_refresh(pcity); + send_city_info(get_player(pcity->owner), pcity); + } } /************************************************************************** @@ -1400,4 +1397,83 @@ 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) +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) +{ + struct city *fromcity = map_get_city(src_x, src_y); + struct city *tocity = map_get_city(dest_x, dest_y); + struct city *homecity = find_city_by_id(punit->homecity); + struct player *pplayer = get_player(punit->owner); + /* struct government *g = get_gov_pplayer(pplayer);*/ + int sentfrom = 0, sentto = 0, senthome = 0; + + teleport_unit_sight_points(src_x, src_y, dest_x, dest_y, punit); + + if(tocity) { /* entering a city */ + if (tocity->owner == punit->owner) { + if (tocity != homecity) { + city_refresh(tocity); + send_city_info(pplayer, tocity); + } + sentto = 1; + } + + handle_unit_enter_city(punit, tocity); + /* if the city belongs to an enemy we conqured it and it doesn't exist any more */ + tocity = map_get_city(dest_x, dest_y); + + if (homecity) { + city_refresh(homecity); + send_city_info(pplayer, homecity); + } + 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); + } + 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); + } + + 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); + } + + wakeup_neighbor_sentries(pplayer, dest_x, dest_y); + + /* punit might get killed by horde of barbarians */ + if((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/unithand.h send_on_disband/server/unithand.h --- freeciv/server/unithand.h Tue Apr 11 16:28:59 2000 +++ send_on_disband/server/unithand.h Tue Apr 11 20:59:54 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 player *pplayer, struct unit *punit, @@ -66,6 +66,7 @@ struct packet_generic_integer *packet); 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); #endif /* FC__UNITHAND_H */ diff -Nur -X/home/thue/freeciv-dev/no.freeciv freeciv/server/unittools.c send_on_disband/server/unittools.c --- freeciv/server/unittools.c Tue Apr 11 16:28:59 2000 +++ send_on_disband/server/unittools.c Tue Apr 11 21:01:41 2000 @@ -698,7 +698,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; @@ -708,6 +707,7 @@ punit->moves_left -= mov_cost; unit_list_insert(&map_get_tile(pcity->x, pcity->y)->units, punit); + handle_unit_move_consequences(punit, src_x, src_y, pcity->x, pcity->y); send_unit_info_to_onlookers(0, punit, src_x,src_y); return 1;