Index: ai/aitools.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aitools.c,v retrieving revision 1.83 diff -u -r1.83 aitools.c --- ai/aitools.c 2003/04/20 11:22:59 1.83 +++ ai/aitools.c 2003/04/29 21:47:09 @@ -90,72 +90,6 @@ } /************************************************************************** - Create a virtual unit to use in build want estimation. pcity can be - NULL. -**************************************************************************/ -struct unit *create_unit_virtual(struct player *pplayer, struct city *pcity, - Unit_Type_id type, bool make_veteran) -{ - struct unit *punit; - punit=fc_calloc(1, sizeof(struct unit)); - - assert(pcity != NULL); - punit->type = type; - punit->owner = pplayer->player_no; - CHECK_MAP_POS(pcity->x, pcity->y); - punit->x = pcity->x; - punit->y = pcity->y; - punit->goto_dest_x = 0; - punit->goto_dest_y = 0; - punit->veteran = make_veteran; - punit->homecity = pcity->id; - punit->upkeep = 0; - punit->upkeep_food = 0; - punit->upkeep_gold = 0; - punit->unhappiness = 0; - /* A unit new and fresh ... */ - punit->foul = FALSE; - punit->fuel = unit_type(punit)->fuel; - punit->hp = unit_type(punit)->hp; - punit->moves_left = unit_move_rate(punit); - punit->moved = FALSE; - punit->paradropped = FALSE; - if (is_barbarian(pplayer)) { - punit->fuel = BARBARIAN_LIFE; - } - /* AI.control is probably always true... */ - punit->ai.control = FALSE; - punit->ai.ai_role = AIUNIT_NONE; - punit->ai.ferryboat = 0; - punit->ai.passenger = 0; - punit->ai.bodyguard = 0; - punit->ai.charge = 0; - punit->bribe_cost = -1; /* flag value */ - punit->transported_by = -1; - punit->pgr = NULL; - set_unit_activity(punit, ACTIVITY_IDLE); - - return punit; -} - -/************************************************************************** - Free the memory used by virtual unit - It is assumed (since it's virtual) that it's not registered or - listed anywhere. -**************************************************************************/ -void destroy_unit_virtual(struct unit *punit) -{ - if (punit->pgr) { - /* Should never happen, but do it anyway for completeness */ - free(punit->pgr->pos); - free(punit->pgr); - punit->pgr = NULL; - } - - free(punit); -} - -/************************************************************************** This will eventually become the ferry-enabled goto. For now, it just wraps ai_unit_goto() **************************************************************************/ Index: ai/aitools.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aitools.h,v retrieving revision 1.37 diff -u -r1.37 aitools.h --- ai/aitools.h 2003/04/20 11:22:59 1.37 +++ ai/aitools.h 2003/04/29 21:47:09 @@ -39,9 +39,6 @@ int military_amortize(struct player *pplayer, struct city *pcity, int value, int delay, int build_cost); -struct unit *create_unit_virtual(struct player *pplayer, struct city *pcity, - Unit_Type_id type, bool make_veteran); -void destroy_unit_virtual(struct unit *punit); int stack_cost(struct unit *pdef); bool ai_unit_gothere(struct unit *punit); Index: common/game.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/game.c,v retrieving revision 1.162 diff -u -r1.162 game.c --- common/game.c 2003/04/29 18:05:28 1.162 +++ common/game.c 2003/04/29 21:47:09 @@ -580,9 +580,8 @@ return idex_lookup_unit(id); } - /************************************************************************** -If in the server use wipe_unit(). + In the server call wipe_unit(), and never this function directly. **************************************************************************/ void game_remove_unit(struct unit *punit) { @@ -594,8 +593,9 @@ unit_name(punit->type), punit->x, punit->y, punit->homecity); pcity = player_find_city_by_id(unit_owner(punit), punit->homecity); - if (pcity) + if (pcity) { unit_list_unlink(&pcity->units_supported, punit); + } if (pcity) { freelog(LOG_DEBUG, "home city %s, %s, (%d %d)", pcity->name, @@ -608,9 +608,10 @@ idex_unregister_unit(punit); - if (is_server) + if (is_server) { dealloc_id(punit->id); - free(punit); + } + destroy_unit_virtual(punit); } /************************************************************************** Index: common/unit.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v retrieving revision 1.171 diff -u -r1.171 unit.c --- common/unit.c 2003/03/11 17:59:26 1.171 +++ common/unit.c 2003/04/29 21:47:10 @@ -21,6 +21,7 @@ #include "game.h" #include "log.h" #include "map.h" +#include "mem.h" #include "player.h" #include "shared.h" #include "support.h" @@ -1403,4 +1404,71 @@ default: return FALSE; } +} + +/************************************************************************** + Create a virtual unit skeleton. pcity can be NULL, but then you need + to set x, y and homecity yourself. +**************************************************************************/ +struct unit *create_unit_virtual(struct player *pplayer, struct city *pcity, + Unit_Type_id type, bool make_veteran) +{ + struct unit *punit = fc_calloc(1, sizeof(struct unit)); + + punit->type = type; + punit->owner = pplayer->player_no; + if (pcity) { + CHECK_MAP_POS(pcity->x, pcity->y); + punit->x = pcity->x; + punit->y = pcity->y; + punit->homecity = pcity->id; + } else { + punit->x = -1; + punit->y = -1; + punit->homecity = 0; + } + punit->goto_dest_x = 0; + punit->goto_dest_y = 0; + punit->veteran = make_veteran; + punit->upkeep = 0; + punit->upkeep_food = 0; + punit->upkeep_gold = 0; + punit->unhappiness = 0; + /* A unit new and fresh ... */ + punit->foul = FALSE; + punit->fuel = unit_type(punit)->fuel; + punit->hp = unit_type(punit)->hp; + punit->moves_left = unit_move_rate(punit); + punit->moved = FALSE; + punit->paradropped = FALSE; + punit->connecting = FALSE; + if (is_barbarian(pplayer)) { + punit->fuel = BARBARIAN_LIFE; + } + punit->ai.control = FALSE; + punit->ai.ai_role = AIUNIT_NONE; + punit->ai.ferryboat = 0; + punit->ai.passenger = 0; + punit->ai.bodyguard = 0; + punit->ai.charge = 0; + punit->bribe_cost = -1; /* flag value */ + punit->transported_by = -1; + punit->pgr = NULL; + set_unit_activity(punit, ACTIVITY_IDLE); + + return punit; +} + +/************************************************************************** + Free the memory used by virtual unit. By the time this function is + called, you should already have unregistered it everywhere. +**************************************************************************/ +void destroy_unit_virtual(struct unit *punit) +{ + if (punit->pgr) { + free(punit->pgr->pos); + free(punit->pgr); + punit->pgr = NULL; + } + free(punit); } Index: common/unit.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/unit.h,v retrieving revision 1.96 diff -u -r1.96 unit.h --- common/unit.h 2003/03/11 17:59:26 1.96 +++ common/unit.h 2003/04/29 21:47:10 @@ -21,6 +21,8 @@ struct goto_route; struct tile; +#define BARBARIAN_LIFE 5 + enum unit_activity { ACTIVITY_IDLE, ACTIVITY_POLLUTION, ACTIVITY_ROAD, ACTIVITY_MINE, ACTIVITY_IRRIGATE, ACTIVITY_FORTIFIED, ACTIVITY_FORTRESS, ACTIVITY_SENTRY, @@ -261,5 +263,9 @@ bool zoc_ok_move(struct unit *punit, int x, int y); bool is_build_or_clean_activity(enum unit_activity activity); + +struct unit *create_unit_virtual(struct player *pplayer, struct city *pcity, + Unit_Type_id type, bool make_veteran); +void destroy_unit_virtual(struct unit *punit); #endif /* FC__UNIT_H */ Index: server/barbarian.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/barbarian.h,v retrieving revision 1.8 diff -u -r1.8 barbarian.h --- server/barbarian.h 2002/12/18 17:36:19 1.8 +++ server/barbarian.h 2003/04/29 21:47:10 @@ -25,8 +25,6 @@ #define UPRISE_CIV_MORE 30 #define UPRISE_CIV_MOST 50 -#define BARBARIAN_LIFE 5 - #define MAP_FACTOR 2000 /* adjust this to get a good uprising frequency */ bool unleash_barbarians(int x, int y); Index: server/unittools.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v retrieving revision 1.218 diff -u -r1.218 unittools.c --- server/unittools.c 2003/04/17 20:06:37 1.218 +++ server/unittools.c 2003/04/29 21:47:11 @@ -1537,108 +1537,76 @@ conn_list_do_unbuffer(&pplayer->connections); } -/************************************************************************** - creates a unit, and set it's initial values, and put it into the right - lists. -**************************************************************************/ - -/* This is a wrapper */ - -struct unit *create_unit(struct player *pplayer, int x, int y, Unit_Type_id type, - bool make_veteran, int homecity_id, int moves_left) +/************************************************************************* + Wrapper of the below +*************************************************************************/ +struct unit *create_unit(struct player *pplayer, int x, int y, + Unit_Type_id type, bool make_veteran, + int homecity_id, int moves_left) { - return create_unit_full(pplayer,x,y,type,make_veteran,homecity_id,moves_left,-1); + return 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 */ +/************************************************************************** + Creates a unit, and set it's initial values, and put it into the right + lists. +**************************************************************************/ struct unit *create_unit_full(struct player *pplayer, int x, int y, - Unit_Type_id type, bool make_veteran, int homecity_id, - int moves_left, int hp_left) + Unit_Type_id type, bool veteran, + int homecity_id, int moves_left, int hp_left) { - struct unit *punit; + struct unit *punit = create_unit_virtual(pplayer, NULL, type, veteran); struct city *pcity; - punit=fc_calloc(1,sizeof(struct unit)); - punit->type=type; - punit->id=get_next_id_number(); + /* Register unit */ + punit->id = get_next_id_number(); idex_register_unit(punit); - punit->owner=pplayer->player_no; CHECK_MAP_POS(x, y); punit->x = x; punit->y = y; - punit->goto_dest_x=0; - punit->goto_dest_y=0; - - pcity=find_city_by_id(homecity_id); - punit->veteran=make_veteran; - punit->homecity=homecity_id; - - if(hp_left == -1) - punit->hp=unit_type(punit)->hp; - else + pcity = find_city_by_id(homecity_id); + punit->homecity = homecity_id; + + if (hp_left >= 0) { + /* Override default full HP */ punit->hp = hp_left; - set_unit_activity(punit, ACTIVITY_IDLE); + } + + if (moves_left >= 0) { + /* Override default full MP */ + punit->moves_left = moves_left; + } + + /* Assume that if moves_left < 0 then the unit is "fresh", + * and not moved; else the unit has had something happen + * to it (eg, bribed) which we treat as equivalent to moved. + * (Otherwise could pass moved arg too...) --dwp */ + punit->moved = (moves_left >= 0); + + /* See if this is a spy that has been moved (corrupt and therefore + * unable to establish an embassy. */ + punit->foul = (moves_left != -1 && unit_flag(punit, F_SPY)); - punit->upkeep=0; - punit->upkeep_food=0; - punit->upkeep_gold=0; - punit->unhappiness=0; - - /* - See if this is a spy that has been moved (corrupt and therefore unable - to establish an embassy. - */ - if(moves_left != -1 && unit_flag(punit, F_SPY)) - punit->foul = TRUE; - else - punit->foul = FALSE; - - punit->fuel=unit_type(punit)->fuel; - punit->ai.control = FALSE; - punit->ai.ai_role = AIUNIT_NONE; - punit->ai.ferryboat = 0; - punit->ai.passenger = 0; - punit->ai.bodyguard = 0; - punit->ai.charge = 0; unit_list_insert(&pplayer->units, punit); unit_list_insert(&map_get_tile(x, y)->units, punit); if (pcity) { + assert(city_owner(pcity) == pplayer); unit_list_insert(&pcity->units_supported, punit); assert(city_owner(pcity) == pplayer); + /* Refresh the unit's homecity. */ + city_refresh(pcity); + send_city_info(pplayer, pcity); } - punit->bribe_cost=-1; /* flag value */ - if(moves_left < 0) - punit->moves_left=unit_move_rate(punit); - else - punit->moves_left=moves_left; - - /* Assume that if moves_left<0 then the unit is "fresh", - and not moved; else the unit has had something happen - to it (eg, bribed) which we treat as equivalent to moved. - (Otherwise could pass moved arg too...) --dwp - */ - punit->moved = (moves_left>=0); - - /* Probably not correct when unit changed owner (e.g. bribe) */ - punit->paradropped = FALSE; - - if( is_barbarian(pplayer) ) - punit->fuel = BARBARIAN_LIFE; - - /* ditto for connecting units */ - punit->connecting = FALSE; - punit->transported_by = -1; - punit->pgr = NULL; - if (map_has_special(x, y, S_FORTRESS) - && unit_profits_of_watchtower(punit)) + && unit_profits_of_watchtower(punit)) { unfog_area(pplayer, punit->x, punit->y, get_watchtower_vision(punit)); - else + } else { unfog_area(pplayer, x, y, unit_type(punit)->vision_range); + } send_unit_info(NULL, punit); maybe_make_contact(x, y, unit_owner(punit)); @@ -1646,21 +1614,12 @@ /* The unit may have changed the available tiles in nearby cities. */ map_city_radius_iterate(x, y, x1, y1) { - struct city *pcity = map_get_city(x1, y1); - if (pcity) { - update_city_tile_status_map(pcity, x, y); - } - } map_city_radius_iterate_end; + struct city *acity = map_get_city(x1, y1); - /* Refresh the unit's homecity. */ - { - struct city *pcity = find_city_by_id(homecity_id); - if (pcity) { - assert(city_owner(pcity) == pplayer); - city_refresh(pcity); - send_city_info(pplayer, pcity); + if (acity) { + update_city_tile_status_map(acity, x, y); } - } + } map_city_radius_iterate_end; sync_cities(); @@ -1687,12 +1646,6 @@ } remove_unit_sight_points(punit); - - if (punit->pgr) { - free(punit->pgr->pos); - free(punit->pgr); - punit->pgr = NULL; - } packet.value = punit->id; players_iterate(pplayer) {