[Freeciv-Dev] (PR#6179) more rigorous handling of transported_by
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
This patch primarily adds a couple of sanity checks on the
transported_by field.
Secondarily it makes two code changes that allow these sanity checks to
pass:
1. Barbarians created on ships must be transported by the ship.
2. When moving a ground unit onto ocean, find a transporter for it.
This should ensure that the transported_by field has a valid value,
which will allow PR#5789 to go forward. It should also allow the
removal of some or most (not all - see Per's explanation in PR#6174)
calls to assign_unit_to_transport.
The only issue is that the sanity check may have some rules issues. It
declares that a ground unit in the ocean must be transported by a
non-ground unit: it cannot be transported by another ground unit which
is then transported by a non-ground unit. This is the case under the
default ruleset (which has no transporters that are ground units) but
possibly not under alternate rulesets. What _should_ be the behavior in
this case? Should we allow recursive transporting?
My suggestion is that a transporter with a capacity of C should use C+1
"spots" if you put it in another transporter. This makes some sense to
me from a realism perspective, and prevents recursive transporting. It
also makes the problem simpler from a technical perspective.
jason
? rc
Index: server/barbarian.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/barbarian.c,v
retrieving revision 1.67
diff -u -r1.67 barbarian.c
--- server/barbarian.c 2003/08/04 15:42:47 1.67
+++ server/barbarian.c 2003/09/17 03:44:57
@@ -383,17 +383,21 @@
(void) create_unit(barbarians, xu, yu,
get_role_unit(L_BARBARIAN_LEADER, 0), FALSE, 0, -1);
} else { /* sea raiders - their units will be veteran */
+ struct unit *punit, ptrans;
+
barbarians = create_barbarian_player(FALSE);
boat = find_a_unit_type(L_BARBARIAN_BOAT,-1);
- (void) create_unit(barbarians, xu, yu, boat, TRUE, 0, -1);
+ ptrans = create_unit(barbarians, xu, yu, boat, TRUE, 0, -1);
cap = get_transporter_capacity(unit_list_get(&map_get_tile(xu, yu)->units,
0));
for (i = 0; i < cap-1; i++) {
unit = find_a_unit_type(L_BARBARIAN_SEA,L_BARBARIAN_SEA_TECH);
- (void) create_unit(barbarians, xu, yu, unit, TRUE, 0, -1);
+ punit = create_unit(barbarians, xu, yu, unit, TRUE, 0, -1);
+ punit->transported_by = ptrans->id;
freelog(LOG_DEBUG, "Created barbarian unit %s", unit_types[unit].name);
}
- (void) create_unit(barbarians, xu, yu,
- get_role_unit(L_BARBARIAN_LEADER, 0), FALSE, 0, -1);
+ punit = create_unit(barbarians, xu, yu,
+ get_role_unit(L_BARBARIAN_LEADER, 0), FALSE, 0, -1);
+ punit->transported_by = ptrans->id;
}
unit_list_iterate(map_get_tile(x, y)->units, punit2) {
Index: server/sanitycheck.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sanitycheck.c,v
retrieving revision 1.31
diff -u -r1.31 sanitycheck.c
--- server/sanitycheck.c 2003/08/01 15:58:08 1.31
+++ server/sanitycheck.c 2003/09/17 03:44:57
@@ -22,11 +22,12 @@
#include "log.h"
#include "map.h"
#include "player.h"
+#include "terrain.h"
#include "unit.h"
#include "maphand.h"
-
#include "sanitycheck.h"
+#include "unittools.h"
#ifndef NDEBUG
@@ -261,6 +262,17 @@
assert(punit->moves_left >= 0);
assert(punit->hp > 0);
+
+ /* Check for ground units in the ocean. */
+ if (is_ocean(map_get_terrain(punit->x, punit->y))
+ && is_ground_unit(punit)) {
+ assert(punit->transported_by != -1);
+ assert(!is_ground_unit(find_unit_by_id(punit->transported_by)));
+ }
+
+ /* Check for over-full transports. */
+ assert(get_transporter_occupancy(punit)
+ <= get_transporter_capacity(punit));
} unit_list_iterate_end;
} players_iterate_end;
}
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.250
diff -u -r1.250 unittools.c
--- server/unittools.c 2003/09/17 02:57:21 1.250
+++ server/unittools.c 2003/09/17 03:44:57
@@ -1404,6 +1404,22 @@
}
}
+/****************************************************************************
+ Expensive function to check how many units are in the transport.
+****************************************************************************/
+int get_transporter_occupancy(struct unit *ptrans)
+{
+ int occupied = 0;
+
+ unit_list_iterate(map_get_tile(ptrans->x, ptrans->y)->units, pcargo) {
+ if (pcargo->transported_by == ptrans->id) {
+ occupied++;
+ }
+ } unit_list_iterate_end;
+
+ return occupied;
+}
+
/**************************************************************************
...
**************************************************************************/
@@ -2894,6 +2910,20 @@
punit->moves_left = MAX(0, punit->moves_left - move_cost);
unit_list_insert(&pdesttile->units, punit);
check_unit_activity(punit);
+
+ /* If the unit needs a transporter, put it on one. */
+ if (is_ground_unit(punit)
+ && is_ocean(pdesttile->terrain)) {
+ 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;
+ break;
+ }
+ } unit_list_iterate_end;
+ assert(punit->transported_by != -1);
+ }
/* set activity to sentry if boarding a ship unless the unit is just
* passing through the ship on its way somewhere else. If the unit is
Index: server/unittools.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.h,v
retrieving revision 1.54
diff -u -r1.54 unittools.h
--- server/unittools.h 2003/09/09 20:10:28 1.54
+++ server/unittools.h 2003/09/17 03:44:57
@@ -29,6 +29,7 @@
/* move check related */
bool is_airunit_refuel_point(int x, int y, struct player *pplayer,
Unit_Type_id type, bool unit_is_on_tile);
+int get_transporter_occupancy(struct unit *ptrans);
/* turn update related */
void player_restore_units(struct player *pplayer);
- [Freeciv-Dev] (PR#6179) more rigorous handling of transported_by,
Jason Short <=
|
|