[Freeciv-Dev] (PR#6174) Loading transports
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://rt.freeciv.org/Ticket/Display.html?id=6174 >
The attached patch implements the rules I put forth in my last e-mail
(in the link above).
- Units are loaded on movement or sentrying.
- Units are unloaded on movement or activation.
- At all other times units remain on the transporter they were put in.
- There is no load command, although the infrastructure for this is put
in place.
I've tested it thoroughly with ground unit transporters, but not
carriers or missile carriers.
jason
Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.198
diff -u -r1.198 unit.c
--- common/unit.c 2004/02/07 10:55:20 1.198
+++ common/unit.c 2004/02/18 08:38:24
@@ -1271,6 +1271,59 @@
return zoc_ok_move_gen(punit, punit->x, punit->y, x, y);
}
+/****************************************************************************
+ Return TRUE iff the unit can exist at this location without a transporter.
+****************************************************************************/
+bool can_unit_exist_at_tile_without_transporter(struct unit *punit,
+ int x, int y)
+{
+ struct tile *ptile = map_get_tile(x, y);
+
+ if (ptile->city) {
+ return TRUE;
+ }
+
+ switch (unit_types[punit->type].move_type) {
+ case LAND_MOVING:
+ return !is_ocean(ptile->terrain);
+ case SEA_MOVING:
+ return is_ocean(ptile->terrain);
+ case AIR_MOVING:
+ case HELI_MOVING:
+ return TRUE;
+ }
+ die("Invalid move type");
+ return FALSE;
+}
+
+/****************************************************************************
+ Return TRUE iff the unit can "survive" at this location without a
+ transporter. This means it can not only exist here but will not run out
+ of fuel.
+****************************************************************************/
+bool can_unit_survive_at_tile_without_transporter(struct unit *punit,
+ int x, int y)
+{
+ if (!can_unit_exist_at_tile_without_transporter(punit, x, y)) {
+ return FALSE;
+ }
+
+ if (map_get_city(x, y)) {
+ return TRUE;
+ }
+
+ switch (unit_types[punit->type].move_type) {
+ case LAND_MOVING:
+ case SEA_MOVING:
+ return TRUE;
+ case AIR_MOVING:
+ case HELI_MOVING:
+ return FALSE;
+ }
+ die("Invalid move type");
+ return TRUE;
+}
+
/**************************************************************************
Convenience wrapper for test_unit_move_to_tile.
**************************************************************************/
Index: common/unit.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.h,v
retrieving revision 1.111
diff -u -r1.111 unit.h
--- common/unit.h 2004/02/07 11:16:50 1.111
+++ common/unit.h 2004/02/18 08:38:24
@@ -303,6 +303,10 @@
bool can_step_taken_wrt_to_zoc(Unit_Type_id type, struct player *unit_owner,
int src_x, int src_y, int dest_x,
int dest_y);
+bool can_unit_exist_at_tile_without_transporter(struct unit *punit,
+ int x, int y);
+bool can_unit_survive_at_tile_without_transporter(struct unit *punit,
+ int x, int y);
bool can_unit_move_to_tile(struct unit *punit, int dest_x, int dest_y,
bool igzoc);
enum unit_move_result test_unit_move_to_tile(Unit_Type_id type,
Index: server/unithand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v
retrieving revision 1.287
diff -u -r1.287 unithand.c
--- server/unithand.c 2004/01/28 06:02:44 1.287
+++ server/unithand.c 2004/02/18 08:38:25
@@ -82,15 +82,6 @@
send_unit_info(NULL, punit);
- /*
- * Normally units on goto does not pick up extra units, even if the
- * units are in a city and are sentried. But if we just started the
- * goto We want to take them with us, so we do this.
- */
- if (get_transporter_capacity(punit) > 0) {
- assign_units_to_transporter(punit, TRUE);
- }
-
(void) do_unit_goto(punit, GOTO_MOVE_ANY, TRUE);
}
@@ -554,6 +545,19 @@
return;
}
+ if (activity == ACTIVITY_IDLE && punit->transported_by != -1
+ && can_unit_survive_at_tile_without_transporter(punit,
+ punit->x, punit->y)) {
+ unload_unit_from_transporter(punit);
+ } else if (activity == ACTIVITY_SENTRY && punit->transported_by == -1) {
+ struct unit *ptrans = find_transporter_for_unit(punit,
+ punit->x, punit->y);
+
+ if (ptrans) {
+ load_unit_onto_transporter(punit, ptrans);
+ }
+ }
+
if (punit->activity != activity ||
punit->activity_target != activity_target ||
punit->ai.control) {
@@ -1074,12 +1078,8 @@
if (can_unit_move_to_tile_with_notify(punit, x, y, igzoc)
&& try_move_unit(punit, x, y)) {
int move_cost = map_move_cost(punit, x, y);
-
- /* The AI should assign the relevant units itself,
- * but for now leave this */
- bool take_from_land = punit->activity == ACTIVITY_IDLE;
- (void) move_unit(punit, x, y, TRUE, take_from_land, move_cost);
+ (void) move_unit(punit, x, y, move_cost);
return TRUE;
} else {
@@ -1550,7 +1550,6 @@
}
#endif
- assign_units_to_transporter(punit, TRUE);
if (execute_orders(punit)) {
/* Looks like the unit survived. */
send_unit_info(NULL, punit);
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.278
diff -u -r1.278 unittools.c
--- server/unittools.c 2004/02/07 11:16:50 1.278
+++ server/unittools.c 2004/02/18 08:38:25
@@ -71,6 +71,10 @@
static bool maybe_cancel_patrol_due_to_enemy(struct unit *punit);
static int hp_gain_coord(struct unit *punit);
+static void put_unit_onto_transporter(struct unit *punit, struct unit *ptrans);
+static void pull_unit_from_transporter(struct unit *punit,
+ struct unit *ptrans);
+
/**************************************************************************
returns a unit type with a given role, use -1 if you don't want a tech
role. Always try tech role and only if not available, return role unit.
@@ -954,7 +958,7 @@
punit2->x, punit2->y, E_UNIT_RELOCATED,
_("Game: Moved your %s due to changing"
" land to sea."), unit_name(punit2->type));
- (void) move_unit(punit2, x, y, TRUE, FALSE, 0);
+ (void) move_unit(punit2, x, y, 0);
if (punit2->activity == ACTIVITY_SENTRY)
handle_unit_activity_request(punit2, ACTIVITY_IDLE);
goto START;
@@ -976,7 +980,7 @@
punit2->x, punit2->y, E_UNIT_RELOCATED,
_("Game: Embarked your %s due to changing"
" land to sea."), unit_name(punit2->type));
- (void) move_unit(punit2, x, y, TRUE, FALSE, 0);
+ (void) move_unit(punit2, x, y, 0);
if (punit2->activity == ACTIVITY_SENTRY)
handle_unit_activity_request(punit2, ACTIVITY_IDLE);
goto START;
@@ -1014,7 +1018,7 @@
punit2->x, punit2->y, E_UNIT_RELOCATED,
_("Game: Moved your %s due to changing"
" sea to land."), unit_name(punit2->type));
- (void) move_unit(punit2, x, y, TRUE, TRUE, 0);
+ (void) move_unit(punit2, x, y, 0);
if (punit2->activity == ACTIVITY_SENTRY)
handle_unit_activity_request(punit2, ACTIVITY_IDLE);
goto START;
@@ -1035,7 +1039,7 @@
punit2->x, punit2->y, E_UNIT_RELOCATED,
_("Game: Docked your %s due to changing"
" sea to land."), unit_name(punit2->type));
- (void) move_unit(punit2, x, y, TRUE, TRUE, 0);
+ (void) move_unit(punit2, x, y, 0);
if (punit2->activity == ACTIVITY_SENTRY)
handle_unit_activity_request(punit2, ACTIVITY_IDLE);
goto START;
@@ -1312,7 +1316,7 @@
if (move_cost == -1)
move_cost = punit->moves_left;
- return move_unit(punit, dest_x, dest_y, FALSE, FALSE, move_cost);
+ return move_unit(punit, dest_x, dest_y, move_cost);
}
return FALSE;
}
@@ -1664,7 +1668,7 @@
if (get_transporter_capacity(punit) > 0) {
unit_list_iterate(map_get_tile(x, y)->units, pcargo) {
if (pcargo->transported_by == punit->id) {
- pcargo->transported_by = -1;
+ pull_unit_from_transporter(pcargo, punit);
}
} unit_list_iterate_end;
}
@@ -1739,7 +1743,7 @@
break;
}
if (is_ground_unit(pcargo) && pcargo->transported_by == -1) {
- pcargo->transported_by = ptrans->id;
+ put_unit_onto_transporter(pcargo, ptrans);
occupancy++;
}
} unit_list_iterate_end;
@@ -2174,6 +2178,9 @@
return FALSE;
if (!unit_can_airlift_to(punit, city2))
return FALSE;
+ if (get_transporter_occupancy(punit) > 0) {
+ return FALSE;
+ }
city1->airlift = FALSE;
city2->airlift = FALSE;
@@ -2181,7 +2188,7 @@
_("Game: %s transported succesfully."),
unit_name(punit->type));
- (void) move_unit(punit, city2->x, city2->y, FALSE, FALSE, punit->moves_left);
+ (void) move_unit(punit, city2->x, city2->y, punit->moves_left);
/* airlift fields have changed. */
send_city_info(city_owner(city1), city1);
@@ -2210,6 +2217,11 @@
return FALSE;
}
+ if (get_transporter_occupancy(punit) > 0) {
+ notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT,
+ _("Game: You cannot paradrop a transporter unit."));
+ }
+
if (!map_is_known(dest_x, dest_y, pplayer)) {
notify_player_ex(pplayer, dest_x, dest_y, E_NOEVENT,
_("Game: The destination location is not known."));
@@ -2275,7 +2287,7 @@
{
int move_cost = unit_type(punit)->paratroopers_mr_sub;
punit->paradropped = TRUE;
- return move_unit(punit, dest_x, dest_y, FALSE, FALSE, move_cost);
+ return move_unit(punit, dest_x, dest_y, move_cost);
}
}
@@ -2451,271 +2463,96 @@
send_player_info(pplayer, pplayer); /* eg, gold */
return ok;
}
-
-/**************************************************************************
- Assigns units on ptrans' tile to ptrans if they should be. This is done
- by setting their transported_by fields to the id of ptrans.
-
- Checks a zillion things, some from situations that should never happen.
- First drop all previously assigned units that do not fit on the
- transport.
- If on land maybe pick up some extra units (decided by take_from_land
- variable)
+/****************************************************************************
+ Return TRUE iff the given transporter can carry the given unit.
+****************************************************************************/
+static bool can_unit_transport_unit(struct unit *ptrans, struct unit *punit)
+{
+ if (ptrans->transported_by != -1) {
+ /* Only top-level transporters allowed. */
+ return FALSE;
+ }
- This function is getting a bit larger and ugly. Perhaps it would be nicer
- if it was recursive!?
+ /* First check unit types. */
+ if (is_ground_unit(punit)) {
+ if (!is_ground_units_transport(ptrans)) {
+ return FALSE;
+ }
+ } else if (unit_flag(punit, F_MISSILE)) {
+ if (!is_air_units_transport(ptrans)) {
+ return FALSE;
+ }
+ } else if (is_air_unit(punit) || is_heli_unit(punit)) {
+ if (!unit_flag(ptrans, F_CARRIER)) {
+ return FALSE;
+ }
+ } else {
+ return FALSE;
+ }
-FIXME: If in the open (not city), and leaving with only those units that are
- already assigned to us would strand some units try to reassign the
- transports. This reassign sometimes makes more changes than it needs to.
+ /* Then check capacity. */
+ return (get_transporter_occupancy(ptrans)
+ < get_transporter_capacity(ptrans));
+}
- Groundunit ground unit transports moving to and from ships never take
- units with them. This is ok, but not always practical.
-**************************************************************************/
-void assign_units_to_transporter(struct unit *ptrans, bool take_from_land)
-{
- int x = ptrans->x;
- int y = ptrans->y;
- int playerid = ptrans->owner;
- int capacity = get_transporter_capacity(ptrans);
+/****************************************************************************
+ Find a transporter at the given location for the unit.
+****************************************************************************/
+struct unit *find_transporter_for_unit(struct unit *punit, int x, int y)
+{
struct tile *ptile = map_get_tile(x, y);
-
- /*** Ground units transports first ***/
- if (is_ground_units_transport(ptrans)) {
- int available =
- ground_unit_transporter_capacity(x, y, unit_owner(ptrans));
-
- /* See how many units are dedicated to this transport, and remove extra
units */
- unit_list_iterate(ptile->units, pcargo) {
- if (pcargo->transported_by == ptrans->id) {
- if (is_ground_unit(pcargo)
- && capacity > 0
- && (is_ocean(ptile->terrain)
- || pcargo->activity == ACTIVITY_SENTRY)
- && (pcargo->owner == playerid
- || pplayers_allied(unit_owner(pcargo), unit_owner(ptrans)))
- && pcargo->id != ptrans->id
- && !(is_ground_unit(ptrans)
- && (is_ocean(ptile->terrain)
- || is_ground_units_transport(pcargo)))) {
- capacity--;
- } else {
- pcargo->transported_by = -1;
- }
- }
- } unit_list_iterate_end;
- /** We are on an ocean tile. All units must get a transport **/
- if (is_ocean(ptile->terrain)) {
- /* While the transport is not full and units will strand if we don't take
- them with we us dedicate them to this transport. */
- if (available - capacity < 0 && !is_ground_unit(ptrans)) {
- unit_list_iterate(ptile->units, pcargo) {
- if (capacity == 0)
- break;
- if (is_ground_unit(pcargo)
- && pcargo->transported_by != ptrans->id
- && (pcargo->owner == playerid
- || pplayers_allied(unit_owner(pcargo), unit_owner(ptrans))))
{
- capacity--;
- pcargo->transported_by = ptrans->id;
- }
- } unit_list_iterate_end;
- }
- } else { /** We are on a land tile **/
- /* If ordered to do so we take extra units with us, provided they
- * are not already committed to another transporter on the tile. */
- if (take_from_land) {
- unit_list_iterate(ptile->units, pcargo) {
- if (capacity == 0)
- break;
- if (is_ground_unit(pcargo)
- && pcargo->transported_by != ptrans->id
- && pcargo->activity == ACTIVITY_SENTRY
- && pcargo->id != ptrans->id
- && pcargo->owner == playerid
- && !(is_ground_unit(ptrans)
- && (is_ocean(ptile->terrain)
- || is_ground_units_transport(pcargo)))) {
- bool has_trans = FALSE;
-
- unit_list_iterate(ptile->units, ptrans2) {
- if (ptrans2->id == pcargo->transported_by)
- has_trans = TRUE;
- } unit_list_iterate_end;
- if (!has_trans) {
- capacity--;
- pcargo->transported_by = ptrans->id;
- }
- }
- } unit_list_iterate_end;
- }
+ unit_list_iterate(ptile->units, ptrans) {
+ if (can_unit_transport_unit(ptrans, punit)) {
+ return ptrans;
}
- return;
- /*** Allocate air and missile units ***/
- } else if (is_air_units_transport(ptrans)) {
- struct player_tile *plrtile =
- map_get_player_tile(x, y, unit_owner(ptrans));
- bool is_refuel_point =
- is_allied_city_tile(map_get_tile(x, y), unit_owner(ptrans))
- || (contains_special(plrtile->special, S_AIRBASE)
- && !is_non_allied_unit_tile(map_get_tile(x, y),
- unit_owner(ptrans)));
- bool missiles_only = unit_flag(ptrans, F_MISSILE_CARRIER)
- && !unit_flag(ptrans, F_CARRIER);
-
- /* Make sure we can transport the units marked as being transported by
ptrans */
- unit_list_iterate(ptile->units, pcargo) {
- if (ptrans->id == pcargo->transported_by) {
- if ((pcargo->owner == playerid
- || pplayers_allied(unit_owner(pcargo), unit_owner(ptrans)))
- && pcargo->id != ptrans->id
- && (!is_sailing_unit(pcargo))
- && (unit_flag(pcargo, F_MISSILE) || !missiles_only)
- && !(is_ground_unit(ptrans) && is_ocean(ptile->terrain))
- && (capacity > 0)) {
- if (is_air_unit(pcargo))
- capacity--;
- /* Ground units are handled below */
- } else
- pcargo->transported_by = -1;
- }
- } unit_list_iterate_end;
+ } unit_list_iterate_end;
- /** We are at a refuel point **/
- if (is_refuel_point) {
- unit_list_iterate(ptile->units, pcargo) {
- if (capacity == 0)
- break;
- if (is_air_unit(pcargo)
- && pcargo->id != ptrans->id
- && pcargo->transported_by != ptrans->id
- && pcargo->activity == ACTIVITY_SENTRY
- && (unit_flag(pcargo, F_MISSILE) || !missiles_only)
- && (pcargo->owner == playerid
- || pplayers_allied(unit_owner(pcargo), unit_owner(ptrans)))) {
- bool has_trans = FALSE;
-
- unit_list_iterate(ptile->units, ptrans2) {
- if (ptrans2->id == pcargo->transported_by)
- has_trans = TRUE;
- } unit_list_iterate_end;
- if (!has_trans) {
- capacity--;
- pcargo->transported_by = ptrans->id;
- }
- }
- } unit_list_iterate_end;
- } else { /** We are in the open. All units must have a transport if
possible **/
- int aircap = airunit_carrier_capacity(x, y, unit_owner(ptrans), TRUE);
- int miscap = missile_carrier_capacity(x, y, unit_owner(ptrans), TRUE);
-
- /* Not enough capacity. Take anything we can */
- if ((aircap < capacity || miscap < capacity)
- && !(is_ground_unit(ptrans) && is_ocean(ptile->terrain))) {
- /* We first take nonmissiles, as missiles can be transported on
anything,
- but nonmissiles can not */
- if (!missiles_only) {
- unit_list_iterate(ptile->units, pcargo) {
- if (capacity == 0)
- break;
- if (is_air_unit(pcargo)
- && pcargo->id != ptrans->id
- && pcargo->transported_by != ptrans->id
- && !unit_flag(pcargo, F_MISSILE)
- && (pcargo->owner == playerid
- || pplayers_allied(unit_owner(pcargo),
unit_owner(ptrans)))) {
- capacity--;
- pcargo->transported_by = ptrans->id;
- }
- } unit_list_iterate_end;
- }
-
- /* Just take anything there's left.
- (which must be missiles if we have capacity left) */
- unit_list_iterate(ptile->units, pcargo) {
- if (capacity == 0)
- break;
- if (is_air_unit(pcargo)
- && pcargo->id != ptrans->id
- && pcargo->transported_by != ptrans->id
- && (!missiles_only || unit_flag(pcargo, F_MISSILE))
- && (pcargo->owner == playerid
- || pplayers_allied(unit_owner(pcargo), unit_owner(ptrans))))
{
- capacity--;
- pcargo->transported_by = ptrans->id;
- }
- } unit_list_iterate_end;
- }
- }
+ return FALSE;
+}
- /** If any of the transported air units have land units on board take them
with us **/
- {
- int totcap = 0;
- int available =
- ground_unit_transporter_capacity(x, y, unit_owner(ptrans));
- struct unit_list trans2s;
- unit_list_init(&trans2s);
-
- unit_list_iterate(ptile->units, pcargo) {
- if (pcargo->transported_by == ptrans->id
- && is_ground_units_transport(pcargo)
- && is_air_unit(pcargo)) {
- totcap += get_transporter_capacity(pcargo);
- unit_list_insert(&trans2s, pcargo);
- }
- } unit_list_iterate_end;
+/****************************************************************************
+ Put the unit onto the transporter. Don't do any other work.
+****************************************************************************/
+static void put_unit_onto_transporter(struct unit *punit, struct unit *ptrans)
+{
+ /* In the future we may updated ptrans->occupancy. */
+ assert(punit->transported_by == -1);
+ punit->transported_by = ptrans->id;
+}
- unit_list_iterate(ptile->units, pcargo2) {
- bool has_trans = FALSE;
+/****************************************************************************
+ Put the unit onto the transporter. Don't do any other work.
+****************************************************************************/
+static void pull_unit_from_transporter(struct unit *punit,
+ struct unit *ptrans)
+{
+ /* In the future we may updated ptrans->occupancy. */
+ assert(punit->transported_by == ptrans->id);
+ punit->transported_by = -1;
+}
- unit_list_iterate(trans2s, ptrans2) {
- if (pcargo2->transported_by == ptrans2->id)
- has_trans = TRUE;
- } unit_list_iterate_end;
- if (pcargo2->transported_by == ptrans->id)
- has_trans = TRUE;
+/****************************************************************************
+ Put the unit onto the transporter, and tell everyone.
+****************************************************************************/
+void load_unit_onto_transporter(struct unit *punit, struct unit *ptrans)
+{
+ put_unit_onto_transporter(punit, ptrans);
+ send_unit_info(NULL, punit);
+ send_unit_info(NULL, ptrans);
+}
- if (has_trans
- && is_ground_unit(pcargo2)) {
- if (totcap > 0
- && (is_ocean(ptile->terrain)
- || pcargo2->activity == ACTIVITY_SENTRY)
- && (pcargo2->owner == playerid
- || pplayers_allied(unit_owner(pcargo2), unit_owner(ptrans)))
- && pcargo2 != ptrans) {
- pcargo2->transported_by = ptrans->id;
- totcap--;
- } else
- pcargo2->transported_by = -1;
- }
- } unit_list_iterate_end;
+/****************************************************************************
+ Pull the unit off of the transporter, and tell everyone.
+****************************************************************************/
+void unload_unit_from_transporter(struct unit *punit)
+{
+ struct unit *ptrans = find_unit_by_id(punit->transported_by);
- /* Uh oh. Not enough space on the square we leave if we don't
- take extra units with us */
- if (totcap > available && is_ocean(ptile->terrain)) {
- unit_list_iterate(ptile->units, pcargo2) {
- if (is_ground_unit(pcargo2)
- && totcap > 0
- && (pcargo2->owner == playerid
- || pplayers_allied(unit_owner(pcargo2), unit_owner(ptrans)))
- && pcargo2->transported_by != ptrans->id) {
- pcargo2->transported_by = ptrans->id;
- totcap--;
- }
- } unit_list_iterate_end;
- }
- }
- } else {
- unit_list_iterate(ptile->units, pcargo) {
- if (ptrans->id == pcargo->transported_by)
- pcargo->transported_by = -1;
- } unit_list_iterate_end;
- freelog (LOG_VERBOSE, "trying to assign cargo to a non-transporter "
- "of type %s at %i,%i",
- get_unit_name(ptrans->type), ptrans->x, ptrans->y);
- }
+ pull_unit_from_transporter(punit, ptrans);
+ send_unit_info(NULL, punit);
+ send_unit_info(NULL, ptrans);
}
/*****************************************************************
@@ -2889,8 +2726,7 @@
if you have set transport_units. Note that the src and dest need not be
adjacent.
**************************************************************************/
-bool move_unit(struct unit *punit, int dest_x, int dest_y,
- bool transport_units, bool take_from_land, int move_cost)
+bool move_unit(struct unit *punit, int dest_x, int dest_y, int move_cost)
{
int src_x = punit->x;
int src_y = punit->y;
@@ -2904,38 +2740,14 @@
conn_list_do_buffer(&pplayer->connections);
- /* A transporter should not take units with it on an attack goto. */
- if ((unit_has_orders(punit)
- || punit->activity == ACTIVITY_GOTO)
- && (is_non_allied_unit_tile(pdesttile, pplayer)
- || is_non_allied_city_tile(pdesttile, pplayer))
- && !is_ocean(psrctile->terrain)) {
- transport_units = FALSE;
- }
-
- /* A ground unit cannot hold units on an ocean tile */
- if (transport_units
- && is_ground_unit(punit)
- && is_ocean(pdesttile->terrain)) {
- transport_units = FALSE;
- }
-
- /* Make sure we don't accidentally insert units into a transporters list */
- unit_list_iterate(pdesttile->units, pcargo) {
- if (pcargo->transported_by == punit->id) {
- pcargo->transported_by = -1;
- }
- } unit_list_iterate_end;
-
/* Transporting units. We first make a list of the units to be moved and
then insert them again. The way this is done makes sure that the
units stay in the same order. */
- if (get_transporter_capacity(punit) > 0 && transport_units) {
+ if (get_transporter_capacity(punit) > 0) {
struct unit_list cargo_units;
/* First make a list of the units to be moved. */
unit_list_init(&cargo_units);
- assign_units_to_transporter(punit, take_from_land);
unit_list_iterate(psrctile->units, pcargo) {
if (pcargo->transported_by == punit->id) {
unit_list_unlink(&psrctile->units, pcargo);
@@ -2979,8 +2791,8 @@
punit->moved = TRUE;
if (punit->transported_by != -1) {
ptransporter = find_unit_by_id(punit->transported_by);
+ pull_unit_from_transporter(punit, ptransporter);
}
- punit->transported_by = -1;
punit->moves_left = MAX(0, punit->moves_left - move_cost);
if (punit->moves_left == 0) {
punit->done_moving = TRUE;
@@ -3007,26 +2819,16 @@
send_unit_info_to_onlookers(NULL, punit, src_x, src_y, FALSE);
/* Special checks for ground units in the ocean. */
- if (!pdesttile->city
- && is_ground_unit(punit)
- && is_ocean(pdesttile->terrain)) {
-
- ptransporter = NULL;
-
- /* Find a transporter for the unit. */
- unit_list_iterate(map_get_tile(punit->x, punit->y)->units, ptrans) {
- if (is_ground_units_transport(ptrans)
- && (get_transporter_occupancy(ptrans)
- < get_transporter_capacity(ptrans))) {
- punit->transported_by = ptrans->id;
- ptransporter = ptrans;
- break;
- }
- } unit_list_iterate_end;
- assert(punit->transported_by != -1);
+ if (!can_unit_survive_at_tile_without_transporter(punit, dest_x, dest_y)) {
+ ptransporter = find_transporter_for_unit(punit, dest_x, dest_y);
+ if (ptransporter) {
+ put_unit_onto_transporter(punit, ptransporter);
+ }
/* Set activity to sentry if boarding a ship. */
- if (!pplayer->ai.control && !unit_has_orders(punit)) {
+ if (ptransporter && !pplayer->ai.control && !unit_has_orders(punit)
+ && !can_unit_exist_at_tile_without_transporter(punit,
+ dest_x, dest_y)) {
set_unit_activity(punit, ACTIVITY_SENTRY);
}
@@ -3037,9 +2839,11 @@
/*
* Send updated information to anyone watching that transporter has cargo.
- */
- send_unit_info(NULL, ptransporter);
-
+ */
+ if (ptransporter) {
+ send_unit_info(NULL, ptransporter);
+ }
+
/*
* Send updated information to anyone watching that unit is on transport.
* All players without shared vison with owner player get
Index: server/unittools.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.h,v
retrieving revision 1.62
diff -u -r1.62 unittools.h
--- server/unittools.h 2004/01/28 06:02:44 1.62
+++ server/unittools.h 2004/02/18 08:38:25
@@ -79,9 +79,10 @@
bool try_move_unit(struct unit *punit, int dest_x, int dest_y);
bool do_airline(struct unit *punit, struct city *city2);
bool do_paradrop(struct unit *punit, int dest_x, int dest_y);
-void assign_units_to_transporter(struct unit *ptrans, bool take_from_land);
-bool move_unit(struct unit *punit, int dest_x, int dest_y,
- bool transport_units, bool take_from_land, int move_cost);
+struct unit *find_transporter_for_unit(struct unit *punit, int x, int y);
+void load_unit_onto_transporter(struct unit *punit, struct unit *ptrans);
+void unload_unit_from_transporter(struct unit *punit);
+bool move_unit(struct unit *punit, int dest_x, int dest_y, int move_cost);
bool execute_orders(struct unit *punit);
#endif /* FC__UNITTOOLS_H */
- [Freeciv-Dev] Re: (PR#6174) Loading transports, Raimar Falke, 2004/02/02
- [Freeciv-Dev] Re: (PR#6174) Loading transports, Jason Short, 2004/02/02
- [Freeciv-Dev] Re: (PR#6174) Loading transports, Raimar Falke, 2004/02/02
- [Freeciv-Dev] Re: (PR#6174) Loading transports, Jason Short, 2004/02/02
- [Freeciv-Dev] (PR#6174) Loading transports, Jason Short, 2004/02/06
- [Freeciv-Dev] (PR#6174) Loading transports,
Jason Short <=
- [Freeciv-Dev] Re: (PR#6174) Loading transports, Per I. Mathisen, 2004/02/27
- [Freeciv-Dev] Re: (PR#6174) Loading transports, Jason Short, 2004/02/27
- [Freeciv-Dev] Re: (PR#6174) Loading transports, Per I. Mathisen, 2004/02/27
|
|