[Freeciv-Dev] Re: (PR#19132) [Bug] Startunits in non-native terrains
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: |
[Freeciv-Dev] Re: (PR#19132) [Bug] Startunits in non-native terrains |
From: |
"Marko Lindqvist" <cazfi74@xxxxxxxxx> |
Date: |
Wed, 16 Aug 2006 13:05:58 -0700 |
Reply-to: |
bugs@xxxxxxxxxxx |
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=19132 >
Marko Lindqvist wrote:
>
> Basically any land tile can be starting place. Startunits are placed
> to that tile even if it's non-native to them. Placing units to
> non-native terrain causes sanitycheck assert.
Patch
- ML
diff -Nurd -X.diff_ignore freeciv/server/gamehand.c freeciv/server/gamehand.c
--- freeciv/server/gamehand.c 2006-08-16 22:09:19.390500000 +0300
+++ freeciv/server/gamehand.c 2006-08-16 22:49:56.984250000 +0300
@@ -59,29 +59,16 @@
}
/****************************************************************************
- Place a starting unit for the player.
+ Place a starting unit for the player. Returns tile where unit was really
+ placed.
****************************************************************************/
-static void place_starting_unit(struct tile *ptile, struct player *pplayer,
- char crole)
+static struct tile *place_starting_unit(struct tile *starttile,
+ struct player *pplayer,
+ char crole)
{
- struct unit_type *utype;
+ struct unit_type *utype = NULL;
enum unit_flag_id role;
-
- assert(!is_non_allied_unit_tile(ptile, pplayer));
-
- /* For scenarios or dispersion, huts may coincide with player starts (in
- * other cases, huts are avoided as start positions). Remove any such hut,
- * and make sure to tell the client, since we may have already sent this
- * tile (with the hut) earlier: */
- if (tile_has_special(ptile, S_HUT)) {
- tile_clear_special(ptile, S_HUT);
- update_tile_knowledge(ptile);
- freelog(LOG_VERBOSE, "Removed hut on start position for %s",
- pplayer->name);
- }
-
- /* Expose visible area. */
- map_show_circle(pplayer, ptile, game.info.init_vis_radius_sq);
+ struct tile *ptile = NULL;
switch(crole) {
case 'c':
@@ -116,7 +103,7 @@
break;
default:
assert(FALSE);
- return;
+ return NULL;
}
/* Create the unit of an appropriate type, if it exists */
@@ -125,7 +112,40 @@
if (utype == NULL) {
utype = get_role_unit(role, 0);
}
+ }
+
+ if (utype != NULL) {
+ iterate_outward(starttile, map.xsize + map.ysize, itertile) {
+ if (!is_non_allied_unit_tile(itertile, pplayer)
+ && is_native_tile(utype, itertile)) {
+ ptile = itertile;
+ break;
+ }
+ } iterate_outward_end;
+ }
+
+ if (ptile == NULL) {
+ /* No place where unit may exist. */
+ return NULL;
+ }
+
+ assert(!is_non_allied_unit_tile(ptile, pplayer));
+
+ /* For scenarios or dispersion, huts may coincide with player starts (in
+ * other cases, huts are avoided as start positions). Remove any such hut,
+ * and make sure to tell the client, since we may have already sent this
+ * tile (with the hut) earlier: */
+ if (tile_has_special(ptile, S_HUT)) {
+ tile_clear_special(ptile, S_HUT);
+ update_tile_knowledge(ptile);
+ freelog(LOG_VERBOSE, "Removed hut on start position for %s",
+ pplayer->name);
+ }
+
+ /* Expose visible area. */
+ map_show_circle(pplayer, ptile, game.info.init_vis_radius_sq);
+ if (utype != NULL) {
/* We cannot currently handle sea units as start units.
* TODO: remove this code block when we can. */
if (get_unit_move_type(utype) == SEA_MOVING) {
@@ -134,11 +154,14 @@
notify_player(pplayer, NULL, E_BAD_COMMAND,
_("Sea moving start units are not yet supported. "
"Nobody gets %s."), utype->name);
- return;
+ return NULL;
}
(void) create_unit(pplayer, ptile, utype, FALSE, 0, 0);
+ return ptile;
}
+
+ return NULL;
}
/****************************************************************************
@@ -170,6 +193,7 @@
{
const int NO_START_POS = -1;
int start_pos[game.info.nplayers];
+ int placed_units[game.info.nplayers];
bool pos_used[map.num_start_positions];
int i, num_used = 0;
@@ -239,7 +263,12 @@
= map.start_positions[start_pos[pplayer->player_no]];
/* Place the first unit. */
- place_starting_unit(pos.tile, pplayer, game.info.start_units[0]);
+ if (place_starting_unit(pos.tile, pplayer,
+ game.info.start_units[0]) != NULL) {
+ placed_units[pplayer->player_no] = 1;
+ } else {
+ placed_units[pplayer->player_no] = 0;
+ }
} players_iterate_end;
/* Place all other units. */
@@ -255,7 +284,10 @@
ptile = find_dispersed_position(pplayer, &p);
/* Create the unit of an appropriate type. */
- place_starting_unit(ptile, pplayer, game.info.start_units[i]);
+ if (place_starting_unit(ptile, pplayer,
+ game.info.start_units[i]) != NULL) {
+ placed_units[pplayer->player_no]++;
+ }
}
/* Place nation specific start units (not role based!) */
@@ -263,10 +295,18 @@
while (nation->init_units[i] != NULL && i < MAX_NUM_UNIT_LIST) {
ptile = find_dispersed_position(pplayer, &p);
create_unit(pplayer, ptile, nation->init_units[i], FALSE, 0, 0);
+ placed_units[pplayer->player_no]++;
i++;
}
} players_iterate_end;
+ players_iterate(pplayer) {
+ if (placed_units[pplayer->player_no] == 0) {
+ /* No units at all for some player! */
+ die(_("No units placed for %s!"), pplayer->name);
+ }
+ } players_iterate_end;
+
shuffle_players();
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Freeciv-Dev] Re: (PR#19132) [Bug] Startunits in non-native terrains,
Marko Lindqvist <=
|
|