[Freeciv-Dev] Re: (PR#13442) access terrains by pointer
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13442 >
Jason Short wrote:
> It's a preliminary patch because it gives a segfault in mapgen. However
> the backtrace for this segfault seems rather useless to me and I've
> spent some time without any luck understanding it at all. If anyone
> wants to give it a run and look at it I'd be appreciative.
Well, as far as I can tell these crashes occur because the current CVS
and 2.0 code is very buggy.
In mapgen, all tiles are initialized to T_UNKNOWN. Then we do all sorts
of iterations and comparisons of tiles in the placement of terrains and
specials. At many points we look at T_UNKNOWN tiles. In the old code
this would result in a buffer underflow and unpredictable behavior
because T_UNKNOWN is -1. However in the new code it causes a crash
outright because T_UNKNOWN is NULL and this is dereferenced.
I'm going to have to look at this a bit closer to make sure I'm missing
something. But for the moment I believe this patch corrects the errors
by checking for T_UNKNOWN before dereferencing. If this is indeed the
problem then S2_0 may need fixing as well.
-jason
? vgcore.pid12865
Index: ai/aisettler.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aisettler.c,v
retrieving revision 1.24
diff -p -u -r1.24 aisettler.c
--- ai/aisettler.c 9 Jul 2005 17:46:06 -0000 1.24
+++ ai/aisettler.c 12 Jul 2005 15:43:22 -0000
@@ -296,7 +296,7 @@ static int defense_bonus(struct cityresu
{
/* Defense modification (as tie breaker mostly) */
int defense_bonus =
- 10 + get_terrain(tile_get_terrain(result->tile))->defense_bonus / 10;
+ 10 + tile_get_terrain(result->tile)->defense_bonus / 10;
if (tile_has_special(result->tile, S_RIVER)) {
defense_bonus +=
(defense_bonus * terrain_control.river_defense_bonus) / 100;
Index: ai/aitools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitools.c,v
retrieving revision 1.153
diff -p -u -r1.153 aitools.c
--- ai/aitools.c 9 Jul 2005 17:46:06 -0000 1.153
+++ ai/aitools.c 12 Jul 2005 15:43:22 -0000
@@ -478,7 +478,7 @@ static double chance_killed_at(const str
double p = is_ocean(ptile->terrain)? 0.05: 0.15;
/* If we are on defensive terrain, we are more likely to survive */
- db = 10 + get_terrain(ptile->terrain)->defense_bonus / 10;
+ db = 10 + ptile->terrain->defense_bonus / 10;
if (tile_has_special(ptile, S_RIVER)) {
db += (db * terrain_control.river_defense_bonus) / 100;
}
Index: ai/aiunit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
retrieving revision 1.363
diff -p -u -r1.363 aiunit.c
--- ai/aiunit.c 9 Jul 2005 17:46:06 -0000 1.363
+++ ai/aiunit.c 12 Jul 2005 15:43:23 -0000
@@ -775,14 +775,14 @@ static bool find_beachhead(struct unit *
struct tile **beachhead_tile)
{
int ok, best = 0;
- Terrain_type_id t;
CHECK_UNIT(punit);
adjc_iterate(dest_tile, tile1) {
+ struct terrain *pterrain = tile_get_terrain(tile1);
+
ok = 0;
- t = tile_get_terrain(tile1);
- if (WARMAP_SEACOST(tile1) <= 6 * THRESHOLD && !is_ocean(t)) {
+ if (WARMAP_SEACOST(tile1) <= 6 * THRESHOLD && !is_ocean(pterrain)) {
/* accessible beachhead */
adjc_iterate(tile1, tile2) {
if (is_ocean(tile_get_terrain(tile2))
@@ -799,10 +799,10 @@ static bool find_beachhead(struct unit *
if (ok > 0) {
/* accessible beachhead with zoc-ok water tile nearby */
- ok = 10 + get_terrain(t)->defense_bonus / 10;
+ ok = 10 + pterrain->defense_bonus / 10;
if (tile_has_special(tile1, S_RIVER))
ok += (ok * terrain_control.river_defense_bonus) / 100;
- if (get_terrain(t)->movement_cost * SINGLE_MOVE <
+ if (pterrain->movement_cost * SINGLE_MOVE <
unit_move_rate(punit))
ok *= 8;
ok += (6 * THRESHOLD - WARMAP_SEACOST(tile1));
Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.181
diff -p -u -r1.181 control.c
--- client/control.c 9 Jul 2005 17:46:07 -0000 1.181
+++ client/control.c 12 Jul 2005 15:43:23 -0000
@@ -696,8 +696,7 @@ static bool is_activity_on_tile(struct t
bool can_unit_do_connect(struct unit *punit, enum unit_activity activity)
{
struct player *pplayer = unit_owner(punit);
- Terrain_type_id terrain = tile_get_terrain(punit->tile);
- struct terrain *ttype = get_terrain(terrain);
+ struct terrain *pterrain = tile_get_terrain(punit->tile);
/* HACK: This code duplicates that in
* can_unit_do_activity_targeted_at(). The general logic here is that
@@ -711,7 +710,7 @@ bool can_unit_do_connect(struct unit *pu
return terrain_control.may_road
&& unit_flag(punit, F_SETTLERS)
&& (tile_has_special(punit->tile, S_ROAD)
- || (ttype->road_time != 0
+ || (pterrain->road_time != 0
&& (!tile_has_special(punit->tile, S_RIVER)
|| player_knows_techs_with_flag(pplayer, TF_BRIDGE))));
case ACTIVITY_RAILROAD:
@@ -727,7 +726,7 @@ bool can_unit_do_connect(struct unit *pu
return (terrain_control.may_irrigate
&& unit_flag(punit, F_SETTLERS)
&& (tile_has_special(punit->tile, S_IRRIGATION)
- || (terrain == ttype->irrigation_result
+ || (pterrain == pterrain->irrigation_result
&& is_water_adjacent_to_tile(punit->tile)
&& !is_activity_on_tile(punit->tile, ACTIVITY_MINE))));
default:
Index: client/goto.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/goto.c,v
retrieving revision 1.88
diff -p -u -r1.88 goto.c
--- client/goto.c 9 Jul 2005 17:46:07 -0000 1.88
+++ client/goto.c 12 Jul 2005 15:43:23 -0000
@@ -390,7 +390,7 @@ static enum tile_behavior get_TB_caravan
static int get_activity_time(const struct tile *ptile,
struct player *pplayer)
{
- struct terrain *ttype = get_terrain(ptile->terrain);
+ struct terrain *pterrain = ptile->terrain;
int activity_mc = 0;
assert(hover_state == HOVER_CONNECT);
@@ -398,7 +398,7 @@ static int get_activity_time(const struc
switch (connect_activity) {
case ACTIVITY_IRRIGATE:
- if (ttype->irrigation_time == 0) {
+ if (pterrain->irrigation_time == 0) {
return -1;
}
if (tile_has_special(ptile, S_MINE)) {
@@ -410,24 +410,24 @@ static int get_activity_time(const struc
break;
}
- activity_mc = ttype->irrigation_time;
+ activity_mc = pterrain->irrigation_time;
break;
case ACTIVITY_RAILROAD:
case ACTIVITY_ROAD:
if (!tile_has_special(ptile, S_ROAD)) {
- if (ttype->road_time == 0
+ if (pterrain->road_time == 0
|| (tile_has_special(ptile, S_RIVER)
&& !player_knows_techs_with_flag(pplayer, TF_BRIDGE))) {
/* 0 means road is impossible here (??) */
return -1;
}
- activity_mc += ttype->road_time;
+ activity_mc += pterrain->road_time;
}
if (connect_activity == ACTIVITY_ROAD
|| tile_has_special(ptile, S_RAILROAD)) {
break;
}
- activity_mc += ttype->rail_time;
+ activity_mc += pterrain->rail_time;
/* No break */
break;
default:
Index: client/helpdata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/helpdata.c,v
retrieving revision 1.118
diff -p -u -r1.118 helpdata.c
--- client/helpdata.c 9 Jul 2005 17:46:07 -0000 1.118
+++ client/helpdata.c 12 Jul 2005 15:43:23 -0000
@@ -115,33 +115,31 @@ void free_help_texts(void)
static void insert_generated_table(const char* name, char* outbuf)
{
if (0 == strcmp (name, "TerrainAlterations")) {
- int i;
-
strcat(outbuf, _("Terrain Road Irrigation Mining "
"Transform\n"));
strcat(outbuf, "---------------------------------------------------"
"------------\n");
- for (i = T_FIRST; i < T_COUNT; i++) {
- if (*(terrains[i].terrain_name) != '\0') {
+ terrain_type_iterate(pterrain) {
+ if (*(pterrain->terrain_name) != '\0') {
outbuf = strchr(outbuf, '\0');
sprintf(outbuf,
"%-10s %3d %3d %-10s %3d %-10s %3d %-10s\n",
- terrains[i].terrain_name,
- terrains[i].road_time,
- terrains[i].irrigation_time,
- ((terrains[i].irrigation_result == i
- || terrains[i].irrigation_result == T_NONE) ? ""
- : terrains[terrains[i].irrigation_result].terrain_name),
- terrains[i].mining_time,
- ((terrains[i].mining_result == i
- || terrains[i].mining_result == T_NONE) ? ""
- : terrains[terrains[i].mining_result].terrain_name),
- terrains[i].transform_time,
- ((terrains[i].transform_result == i
- || terrains[i].transform_result == T_NONE) ? ""
- : terrains[terrains[i].transform_result].terrain_name));
+ pterrain->terrain_name,
+ pterrain->road_time,
+ pterrain->irrigation_time,
+ ((pterrain->irrigation_result == pterrain
+ || pterrain->irrigation_result == T_NONE) ? ""
+ : pterrain->irrigation_result->terrain_name),
+ pterrain->mining_time,
+ ((pterrain->mining_result == pterrain
+ || pterrain->mining_result == T_NONE) ? ""
+ : pterrain->mining_result->terrain_name),
+ pterrain->transform_time,
+ ((pterrain->transform_result == pterrain
+ || pterrain->transform_result == T_NONE) ? ""
+ : pterrain->transform_result->terrain_name));
}
- }
+ } terrain_type_iterate_end;
strcat(outbuf, "\n");
strcat(outbuf, _("(Railroads and fortresses require 3 turns, "
"regardless of terrain.)"));
@@ -387,16 +385,16 @@ void boot_help_texts(void)
}
} tech_type_iterate_end;
} else if (current_type == HELP_TERRAIN) {
- for (i = T_FIRST; i < T_COUNT; i++) {
- if (*(terrains[i].terrain_name) != '\0') {
+ terrain_type_iterate(pterrain) {
+ if (*(pterrain->terrain_name) != '\0') {
pitem = new_help_item(current_type);
my_snprintf(name, sizeof(name), " %s",
- terrains[i].terrain_name);
+ pterrain->terrain_name);
pitem->topic = mystrdup(name);
pitem->text = mystrdup("");
help_list_append(category_nodes, pitem);
}
- }
+ } terrain_type_iterate_end;
/* Add special Civ2-style river help text if it's supplied. */
if (terrain_control.river_help_text) {
pitem = new_help_item(HELP_TEXT);
@@ -1184,50 +1182,48 @@ void helptext_tech(char *buf, int i, con
/****************************************************************
Append text for terrain.
*****************************************************************/
-void helptext_terrain(char *buf, int i, const char *user_text)
+void helptext_terrain(char *buf, const struct terrain *pterrain,
+ const char *user_text)
{
- struct terrain *pt;
-
buf[0] = '\0';
- if (i < 0 || i >= T_COUNT) {
- freelog(LOG_ERROR, "Unknown terrain %d.", i);
+ if (!pterrain) {
+ freelog(LOG_ERROR, "Unknown terrain!");
return;
}
- pt = &terrains[i];
- if (terrain_has_flag(i, TER_NO_POLLUTION)) {
+ if (terrain_has_flag(pterrain, TER_NO_POLLUTION)) {
sprintf(buf + strlen(buf),
_("* Pollution cannot be generated on this terrain."));
strcat(buf, "\n");
}
- if (terrain_has_flag(i, TER_NO_CITIES)) {
+ if (terrain_has_flag(pterrain, TER_NO_CITIES)) {
sprintf(buf + strlen(buf),
_("* You cannot build cities on this terrain."));
strcat(buf, "\n");
}
- if (terrain_has_flag(i, TER_UNSAFE_COAST)
- && !is_ocean(i)) {
+ if (terrain_has_flag(pterrain, TER_UNSAFE_COAST)
+ && !is_ocean(pterrain)) {
sprintf(buf + strlen(buf),
_("* The coastline of this terrain is unsafe."));
strcat(buf, "\n");
}
- if (terrain_has_flag(i, TER_UNSAFE)) {
+ if (terrain_has_flag(pterrain, TER_UNSAFE)) {
sprintf(buf + strlen(buf),
_("* This terrain is unsafe for units to travel on."));
strcat(buf, "\n");
}
- if (terrain_has_flag(i, TER_OCEANIC)) {
+ if (terrain_has_flag(pterrain, TER_OCEANIC)) {
sprintf(buf + strlen(buf),
_("* Land units cannot travel on oceanic terrains."));
strcat(buf, "\n");
}
- if (pt->helptext[0] != '\0') {
+ if (pterrain->helptext[0] != '\0') {
if (buf[0] != '\0') {
strcat(buf, "\n");
}
- sprintf(buf + strlen(buf), "%s", _(pt->helptext));
+ sprintf(buf + strlen(buf), "%s", _(pterrain->helptext));
}
if (user_text && user_text[0] != '\0') {
strcat(buf, "\n\n");
Index: client/helpdata.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/helpdata.h,v
retrieving revision 1.13
diff -p -u -r1.13 helpdata.h
--- client/helpdata.h 30 Apr 2005 17:09:25 -0000 1.13
+++ client/helpdata.h 12 Jul 2005 15:43:23 -0000
@@ -42,7 +42,8 @@ char *helptext_building(char *buf, size_
const char *user_text);
void helptext_unit(char *buf, int i, const char *user_text);
void helptext_tech(char *buf, int i, const char *user_text);
-void helptext_terrain(char *buf, int i, const char *user_text);
+void helptext_terrain(char *buf, const struct terrain *pterrain,
+ const char *user_text);
void helptext_government(char *buf, int i, const char *user_text);
char *helptext_unit_upkeep_str(int i);
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.528
diff -p -u -r1.528 packhand.c
--- client/packhand.c 9 Jul 2005 17:46:07 -0000 1.528
+++ client/packhand.c 12 Jul 2005 15:43:24 -0000
@@ -1861,9 +1861,9 @@ void handle_tile_info(struct packet_tile
bool known_changed = FALSE;
enum tile_special_type spe;
- if (ptile->terrain != packet->type) { /*terrain*/
+ if (!ptile->terrain || ptile->terrain->index != packet->type) {
tile_changed = TRUE;
- ptile->terrain = packet->type;
+ ptile->terrain = get_terrain(packet->type);
}
for (spe = 0; spe < S_LAST; spe++) {
if (packet->special[spe]) {
@@ -2273,62 +2273,61 @@ void handle_ruleset_government_ruler_tit
**************************************************************************/
void handle_ruleset_terrain(struct packet_ruleset_terrain *p)
{
- struct terrain *t;
+ struct terrain *pterrain = get_terrain(p->id);
- if (p->id < T_FIRST || p->id >= T_COUNT) {
+ if (!pterrain) {
freelog(LOG_ERROR,
"Received bad terrain id %d in handle_ruleset_terrain",
p->id);
return;
}
- t = &(terrains[p->id]);
- sz_strlcpy(t->terrain_name_orig, p->terrain_name);
- t->terrain_name = t->terrain_name_orig;
- sz_strlcpy(t->graphic_str, p->graphic_str);
- sz_strlcpy(t->graphic_alt, p->graphic_alt);
- t->movement_cost = p->movement_cost;
- t->defense_bonus = p->defense_bonus;
+ sz_strlcpy(pterrain->terrain_name_orig, p->terrain_name);
+ pterrain->terrain_name = pterrain->terrain_name_orig;
+ sz_strlcpy(pterrain->graphic_str, p->graphic_str);
+ sz_strlcpy(pterrain->graphic_alt, p->graphic_alt);
+ pterrain->movement_cost = p->movement_cost;
+ pterrain->defense_bonus = p->defense_bonus;
output_type_iterate(o) {
- t->output[o] = p->output[o];
- t->special[0].output[o] = p->output_special_1[o];
- t->special[1].output[o] = p->output_special_2[o];
+ pterrain->output[o] = p->output[o];
+ pterrain->special[0].output[o] = p->output_special_1[o];
+ pterrain->special[1].output[o] = p->output_special_2[o];
} output_type_iterate_end;
- sz_strlcpy(t->special[0].name_orig, p->special_1_name);
- t->special[0].name = t->special[0].name_orig;
+ sz_strlcpy(pterrain->special[0].name_orig, p->special_1_name);
+ pterrain->special[0].name = pterrain->special[0].name_orig;
- sz_strlcpy(t->special[1].name_orig, p->special_2_name);
- t->special[1].name = t->special[1].name_orig;
+ sz_strlcpy(pterrain->special[1].name_orig, p->special_2_name);
+ pterrain->special[1].name = pterrain->special[1].name_orig;
- sz_strlcpy(t->special[0].graphic_str, p->graphic_str_special_1);
- sz_strlcpy(t->special[0].graphic_alt, p->graphic_alt_special_1);
+ sz_strlcpy(pterrain->special[0].graphic_str, p->graphic_str_special_1);
+ sz_strlcpy(pterrain->special[0].graphic_alt, p->graphic_alt_special_1);
- sz_strlcpy(t->special[1].graphic_str, p->graphic_str_special_2);
- sz_strlcpy(t->special[1].graphic_alt, p->graphic_alt_special_2);
-
- t->road_time = p->road_time;
- t->road_trade_incr = p->road_trade_incr;
- t->irrigation_result = p->irrigation_result;
- t->irrigation_food_incr = p->irrigation_food_incr;
- t->irrigation_time = p->irrigation_time;
- t->mining_result = p->mining_result;
- t->mining_shield_incr = p->mining_shield_incr;
- t->mining_time = p->mining_time;
- t->transform_result = p->transform_result;
- t->transform_time = p->transform_time;
- t->rail_time = p->rail_time;
- t->airbase_time = p->airbase_time;
- t->fortress_time = p->fortress_time;
- t->clean_pollution_time = p->clean_pollution_time;
- t->clean_fallout_time = p->clean_fallout_time;
+ sz_strlcpy(pterrain->special[1].graphic_str, p->graphic_str_special_2);
+ sz_strlcpy(pterrain->special[1].graphic_alt, p->graphic_alt_special_2);
+
+ pterrain->road_time = p->road_time;
+ pterrain->road_trade_incr = p->road_trade_incr;
+ pterrain->irrigation_result = get_terrain(p->irrigation_result);
+ pterrain->irrigation_food_incr = p->irrigation_food_incr;
+ pterrain->irrigation_time = p->irrigation_time;
+ pterrain->mining_result = get_terrain(p->mining_result);
+ pterrain->mining_shield_incr = p->mining_shield_incr;
+ pterrain->mining_time = p->mining_time;
+ pterrain->transform_result = get_terrain(p->transform_result);
+ pterrain->transform_time = p->transform_time;
+ pterrain->rail_time = p->rail_time;
+ pterrain->airbase_time = p->airbase_time;
+ pterrain->fortress_time = p->fortress_time;
+ pterrain->clean_pollution_time = p->clean_pollution_time;
+ pterrain->clean_fallout_time = p->clean_fallout_time;
- t->flags = p->flags;
+ pterrain->flags = p->flags;
- t->helptext = mystrdup(p->helptext);
+ pterrain->helptext = mystrdup(p->helptext);
- tileset_setup_tile_type(tileset, p->id);
+ tileset_setup_tile_type(tileset, pterrain);
}
/**************************************************************************
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.313
diff -p -u -r1.313 tilespec.c
--- client/tilespec.c 9 Jul 2005 17:46:07 -0000 1.313
+++ client/tilespec.c 12 Jul 2005 15:43:25 -0000
@@ -878,9 +878,9 @@ void tilespec_reread(const char *new_til
/* The ruleset data is not sent until this point. */
return;
}
- for (id = T_FIRST; id < T_COUNT; id++) {
- tileset_setup_tile_type(tileset, id);
- }
+ terrain_type_iterate(pterrain) {
+ tileset_setup_tile_type(tileset, pterrain);
+ } terrain_type_iterate_end;
unit_type_iterate(id) {
tileset_setup_unit_type(tileset, id);
} unit_type_iterate_end;
@@ -2390,23 +2390,24 @@ void tileset_setup_tech_type(struct tile
Set tile_type sprite values; should only happen after
tilespec_load_tiles().
***********************************************************************/
-void tileset_setup_tile_type(struct tileset *t, Terrain_type_id terrain)
+void tileset_setup_tile_type(struct tileset *t,
+ const struct terrain *pterrain)
{
- struct terrain *tt = get_terrain(terrain);
struct terrain_drawing_data *draw;
char buffer1[MAX_LEN_NAME + 20];
int i, l;
- if (tt->terrain_name[0] == '\0') {
+ if (pterrain->terrain_name[0] == '\0') {
return;
}
- draw = hash_lookup_data(t->terrain_hash, tt->graphic_str);
+ draw = hash_lookup_data(t->terrain_hash, pterrain->graphic_str);
if (!draw) {
- draw = hash_lookup_data(t->terrain_hash, tt->graphic_alt);
+ draw = hash_lookup_data(t->terrain_hash, pterrain->graphic_alt);
if (!draw) {
freelog(LOG_FATAL, "No graphics %s or %s for %s terrain.",
- tt->graphic_str, tt->graphic_alt, tt->terrain_name);
+ pterrain->graphic_str, pterrain->graphic_alt,
+ pterrain->terrain_name);
exit(EXIT_FAILURE);
}
}
@@ -2443,7 +2444,7 @@ void tileset_setup_tile_type(struct tile
"t.%s_%s", draw->name, cardinal_index_str(t, i));
draw->layer[l].match[i] = lookup_sprite_tag_alt(t, buffer1, "", TRUE,
"tile_type",
- tt->terrain_name);
+
pterrain->terrain_name);
}
draw->layer[l].base.p[0] = draw->layer[l].match[0];
break;
@@ -2474,7 +2475,7 @@ void tileset_setup_tile_type(struct tile
(value >> 2) & 1);
draw->layer[l].cells[i]
= lookup_sprite_tag_alt(t, buffer1, "", TRUE, "tile_type",
- tt->terrain_name);
+ pterrain->terrain_name);
break;
case MATCH_FULL:
{
@@ -2550,7 +2551,7 @@ void tileset_setup_tile_type(struct tile
my_snprintf(buffer1, sizeof(buffer1), "t.%s1", draw->name);
draw->layer[l].base.p[0]
= lookup_sprite_tag_alt(t, buffer1, "", FALSE, "tile_type",
- tt->terrain_name);
+ pterrain->terrain_name);
break;
}
}
@@ -2574,12 +2575,12 @@ void tileset_setup_tile_type(struct tile
}
for (i = 0; i < MAX_NUM_SPECIALS; i++) {
- const char *name = tt->special[i].name;
+ const char *name = pterrain->special[i].name;
if (name[0] != '\0') {
draw->special[i]
- = lookup_sprite_tag_alt(t, tt->special[i].graphic_str,
- tt->special[i].graphic_alt,
+ = lookup_sprite_tag_alt(t, pterrain->special[i].graphic_str,
+ pterrain->special[i].graphic_alt,
TRUE, "tile_type special", name);
assert(draw->special[i] != NULL);
} else {
@@ -2594,7 +2595,7 @@ void tileset_setup_tile_type(struct tile
draw->mine = NULL;
}
- t->sprites.terrain[terrain] = draw;
+ t->sprites.terrain[pterrain->index] = draw;
}
/**********************************************************************
@@ -2743,28 +2744,28 @@ static struct sprite *get_city_occupied_
tspecial_near : specials of all adjacent terrain
**************************************************************************/
static void build_tile_data(const struct tile *ptile,
- Terrain_type_id *ttype,
+ struct terrain **tterrain,
bv_special *tspecial,
- Terrain_type_id *ttype_near,
+ struct terrain **tterrain_near,
bv_special *tspecial_near)
{
enum direction8 dir;
*tspecial = tile_get_special(ptile);
- *ttype = tile_get_terrain(ptile);
+ *tterrain = tile_get_terrain(ptile);
/* Loop over all adjacent tiles. We should have an iterator for this. */
for (dir = 0; dir < 8; dir++) {
struct tile *tile1 = mapstep(ptile, dir);
if (tile1 && client_tile_get_known(tile1) != TILE_UNKNOWN) {
+ tterrain_near[dir] = tile_get_terrain(tile1);
tspecial_near[dir] = tile_get_special(tile1);
- ttype_near[dir] = tile_get_terrain(tile1);
} else {
/* We draw the edges of the (known) map as if the same terrain just
* continued off the edge of the map. */
+ tterrain_near[dir] = *tterrain;
BV_CLR_ALL(tspecial_near[dir]);
- ttype_near[dir] = *ttype;
}
}
}
@@ -3298,12 +3299,12 @@ static int fill_city_overlays_sprite_arr
static int fill_blending_sprite_array(const struct tileset *t,
struct drawn_sprite *sprs,
const struct tile *ptile,
- Terrain_type_id *ttype_near)
+ struct terrain **tterrain_near)
{
struct drawn_sprite *saved_sprs = sprs;
- Terrain_type_id ttype = tile_get_terrain(ptile);
+ struct terrain *pterrain = tile_get_terrain(ptile);
- if (t->is_isometric && t->sprites.terrain[ttype]->is_blended) {
+ if (t->is_isometric && t->sprites.terrain[pterrain->index]->is_blended) {
enum direction4 dir;
const int W = t->normal_tile_width, H = t->normal_tile_height;
const int offsets[4][2] = {
@@ -3317,16 +3318,16 @@ static int fill_blending_sprite_array(co
*/
for (dir = 0; dir < 4; dir++) {
struct tile *tile1 = mapstep(ptile, DIR4_TO_DIR8[dir]);
- Terrain_type_id other = ttype_near[DIR4_TO_DIR8[dir]];
+ struct terrain *other = tterrain_near[DIR4_TO_DIR8[dir]];
if (!tile1
|| client_tile_get_known(tile1) == TILE_UNKNOWN
- || other == ttype
- || !t->sprites.terrain[other]->is_blended) {
+ || other == pterrain
+ || !t->sprites.terrain[other->index]->is_blended) {
continue;
}
- ADD_SPRITE(t->sprites.terrain[other]->blend[dir], TRUE,
+ ADD_SPRITE(t->sprites.terrain[other->index]->blend[dir], TRUE,
offsets[dir][0], offsets[dir][1]);
}
}
@@ -3394,12 +3395,12 @@ static int fill_terrain_sprite_array(str
struct drawn_sprite *sprs,
int layer,
const struct tile *ptile,
- Terrain_type_id *ttype_near)
+ struct terrain **tterrain_near)
{
struct drawn_sprite *saved_sprs = sprs;
struct sprite *sprite;
- Terrain_type_id ttype = ptile->terrain;
- struct terrain_drawing_data *draw = t->sprites.terrain[ttype];
+ struct terrain *pterrain = ptile->terrain;
+ struct terrain_drawing_data *draw = t->sprites.terrain[pterrain->index];
const int l = layer;
int i, tileno;
struct tile *adjc_tile;
@@ -3444,8 +3445,9 @@ static int fill_terrain_sprite_array(str
int match_type = draw->layer[l].match_type;
#define MATCH(dir) \
- (t->sprites.terrain[ttype_near[(dir)]]->num_layers > l \
- ? t->sprites.terrain[ttype_near[(dir)]]->layer[l].match_type : -1)
+ (t->sprites.terrain[tterrain_near[(dir)]->index]->num_layers > l \
+ ? t->sprites.terrain[tterrain_near[(dir)]->index]->layer[l].match_type \
+ : -1)
if (draw->layer[l].cell_type == CELL_SINGLE) {
int ox = draw->layer[l].offset_x, oy = draw->layer[l].offset_y;
@@ -3525,7 +3527,7 @@ static int fill_terrain_sprite_array(str
/* Add blending on top of the first layer. */
if (l == 0 && draw->is_blended) {
- sprs += fill_blending_sprite_array(t, sprs, ptile, ttype_near);
+ sprs += fill_blending_sprite_array(t, sprs, ptile, tterrain_near);
}
/* Add darkness on top of the first layer. Note that darkness is always
@@ -3767,7 +3769,7 @@ int fill_sprite_array(struct tileset *t,
const struct unit *punit, const struct city *pcity,
const struct city *citymode)
{
- Terrain_type_id ttype = T_UNKNOWN, ttype_near[8];
+ struct terrain *pterrain = NULL, *tterrain_near[8];
bv_special tspecial, tspecial_near[8];
int tileno, dir;
struct unit *pfocus = get_unit_in_focus();
@@ -3812,7 +3814,7 @@ int fill_sprite_array(struct tileset *t,
if (ptile && client_tile_get_known(ptile) != TILE_UNKNOWN) {
build_tile_data(ptile,
- &ttype, &tspecial, ttype_near, tspecial_near);
+ &pterrain, &tspecial, tterrain_near, tspecial_near);
}
switch (layer) {
@@ -3840,13 +3842,13 @@ int fill_sprite_array(struct tileset *t,
assert(MAX_NUM_LAYERS == 2);
sprs += fill_terrain_sprite_array(t, sprs,
(layer == LAYER_TERRAIN1) ? 0 : 1,
- ptile, ttype_near);
+ ptile, tterrain_near);
}
break;
case LAYER_WATER:
if (ptile && client_tile_get_known(ptile) != TILE_UNKNOWN) {
- if (is_ocean(ttype) && draw_terrain && !solid_bg) {
+ if (is_ocean(pterrain) && draw_terrain && !solid_bg) {
for (dir = 0; dir < 4; dir++) {
if (contains_special(tspecial_near[DIR4_TO_DIR8[dir]], S_RIVER)) {
ADD_SPRITE_SIMPLE(t->sprites.tx.river_outlet[dir]);
@@ -3866,7 +3868,7 @@ int fill_sprite_array(struct tileset *t,
enum direction8 dir = t->cardinal_tileset_dirs[i];
if (contains_special(tspecial_near[dir], S_RIVER)
- || is_ocean(ttype_near[dir])) {
+ || is_ocean(tterrain_near[dir])) {
tileno |= 1 << i;
}
}
@@ -3886,9 +3888,9 @@ int fill_sprite_array(struct tileset *t,
if (ptile && client_tile_get_known(ptile) != TILE_UNKNOWN) {
if (draw_specials) {
if (contains_special(tspecial, S_SPECIAL_1)) {
- ADD_SPRITE_SIMPLE(t->sprites.terrain[ttype]->special[0]);
+ ADD_SPRITE_SIMPLE(t->sprites.terrain[pterrain->index]->special[0]);
} else if (contains_special(tspecial, S_SPECIAL_2)) {
- ADD_SPRITE_SIMPLE(t->sprites.terrain[ttype]->special[1]);
+ ADD_SPRITE_SIMPLE(t->sprites.terrain[pterrain->index]->special[1]);
}
}
@@ -3898,8 +3900,8 @@ int fill_sprite_array(struct tileset *t,
}
if (draw_mines && contains_special(tspecial, S_MINE)
- && t->sprites.terrain[ttype]->mine) {
- ADD_SPRITE_SIMPLE(t->sprites.terrain[ttype]->mine);
+ && t->sprites.terrain[pterrain->index]->mine) {
+ ADD_SPRITE_SIMPLE(t->sprites.terrain[pterrain->index]->mine);
}
if (draw_specials && contains_special(tspecial, S_HUT)) {
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.154
diff -p -u -r1.154 tilespec.h
--- client/tilespec.h 22 May 2005 18:12:52 -0000 1.154
+++ client/tilespec.h 12 Jul 2005 15:43:25 -0000
@@ -115,7 +115,8 @@ void tileset_setup_specialist_type(struc
void tileset_setup_unit_type(struct tileset *t, int id);
void tileset_setup_impr_type(struct tileset *t, int id);
void tileset_setup_tech_type(struct tileset *t, int id);
-void tileset_setup_tile_type(struct tileset *t, Terrain_type_id terrain);
+void tileset_setup_tile_type(struct tileset *t,
+ const struct terrain *pterrain);
void tileset_setup_government(struct tileset *t, int id);
void tileset_setup_nation_flag(struct tileset *t, int id);
void tileset_setup_city_tiles(struct tileset *t, int style);
Index: client/gui-gtk-2.0/helpdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/helpdlg.c,v
retrieving revision 1.54
diff -p -u -r1.54 helpdlg.c
--- client/gui-gtk-2.0/helpdlg.c 9 Jul 2005 17:46:07 -0000 1.54
+++ client/gui-gtk-2.0/helpdlg.c 12 Jul 2005 15:43:25 -0000
@@ -1023,104 +1023,104 @@ static void help_update_tech(const struc
...
**************************************************************************/
static void help_update_terrain(const struct help_item *pitem,
- char *title, int i)
+ char *title, struct terrain *pterrain)
{
char *buf = &long_buffer[0];
create_help_page(HELP_TERRAIN);
- if (i < T_COUNT) {
+ if (pterrain) {
sprintf(buf, "%d/%d.%d",
- terrains[i].movement_cost,
- (int)((terrains[i].defense_bonus + 100) / 100),
- (terrains[i].defense_bonus + 100) % 100 / 10);
+ pterrain->movement_cost,
+ (int)((pterrain->defense_bonus + 100) / 100),
+ (pterrain->defense_bonus + 100) % 100 / 10);
gtk_label_set_text(GTK_LABEL(help_tlabel[0][1]), buf);
sprintf(buf, "%d/%d/%d",
- terrains[i].output[O_FOOD],
- terrains[i].output[O_SHIELD],
- terrains[i].output[O_TRADE]);
+ pterrain->output[O_FOOD],
+ pterrain->output[O_SHIELD],
+ pterrain->output[O_TRADE]);
gtk_label_set_text(GTK_LABEL(help_tlabel[0][4]), buf);
- if (*(terrains[i].special[0].name)) {
+ if (*(pterrain->special[0].name)) {
sprintf(buf, _("%s F/R/T:"),
- terrains[i].special[0].name);
+ pterrain->special[0].name);
gtk_label_set_text(GTK_LABEL(help_tlabel[1][0]), buf);
sprintf(buf, "%d/%d/%d",
- terrains[i].special[0].output[O_FOOD],
- terrains[i].special[0].output[O_SHIELD],
- terrains[i].special[0].output[O_TRADE]);
+ pterrain->special[0].output[O_FOOD],
+ pterrain->special[0].output[O_SHIELD],
+ pterrain->special[0].output[O_TRADE]);
gtk_label_set_text(GTK_LABEL(help_tlabel[1][1]), buf);
} else {
gtk_label_set_text(GTK_LABEL(help_tlabel[1][0]), "");
gtk_label_set_text(GTK_LABEL(help_tlabel[1][1]), "");
}
- if (*(terrains[i].special[1].name)) {
+ if (*(pterrain->special[1].name)) {
sprintf(buf, _("%s F/R/T:"),
- terrains[i].special[1].name);
+ pterrain->special[1].name);
gtk_label_set_text(GTK_LABEL(help_tlabel[1][3]), buf);
sprintf(buf, "%d/%d/%d",
- terrains[i].special[1].output[O_FOOD],
- terrains[i].special[1].output[O_SHIELD],
- terrains[i].special[1].output[O_TRADE]);
+ pterrain->special[1].output[O_FOOD],
+ pterrain->special[1].output[O_SHIELD],
+ pterrain->special[1].output[O_TRADE]);
gtk_label_set_text(GTK_LABEL(help_tlabel[1][4]), buf);
} else {
gtk_label_set_text(GTK_LABEL(help_tlabel[1][3]), "");
gtk_label_set_text(GTK_LABEL(help_tlabel[1][4]), "");
}
- if (terrains[i].road_trade_incr > 0) {
+ if (pterrain->road_trade_incr > 0) {
sprintf(buf, _("+%d Trade / %d"),
- terrains[i].road_trade_incr,
- terrains[i].road_time);
- } else if (terrains[i].road_time > 0) {
+ pterrain->road_trade_incr,
+ pterrain->road_time);
+ } else if (pterrain->road_time > 0) {
sprintf(buf, _("no extra / %d"),
- terrains[i].road_time);
+ pterrain->road_time);
} else {
strcpy(buf, _("n/a"));
}
gtk_label_set_text(GTK_LABEL(help_tlabel[2][1]), buf);
strcpy(buf, _("n/a"));
- if (terrains[i].irrigation_result == i) {
- if (terrains[i].irrigation_food_incr > 0) {
+ if (pterrain->irrigation_result == pterrain) {
+ if (pterrain->irrigation_food_incr > 0) {
sprintf(buf, _("+%d Food / %d"),
- terrains[i].irrigation_food_incr,
- terrains[i].irrigation_time);
+ pterrain->irrigation_food_incr,
+ pterrain->irrigation_time);
}
- } else if (terrains[i].irrigation_result != T_NONE) {
+ } else if (pterrain->irrigation_result != T_NONE) {
sprintf(buf, "%s / %d",
- terrains[terrains[i].irrigation_result].terrain_name,
- terrains[i].irrigation_time);
+ pterrain->irrigation_result->terrain_name,
+ pterrain->irrigation_time);
}
gtk_label_set_text(GTK_LABEL(help_tlabel[2][4]), buf);
strcpy(buf, _("n/a"));
- if (terrains[i].mining_result == i) {
- if (terrains[i].mining_shield_incr > 0) {
+ if (pterrain->mining_result == pterrain) {
+ if (pterrain->mining_shield_incr > 0) {
sprintf(buf, _("+%d Res. / %d"),
- terrains[i].mining_shield_incr,
- terrains[i].mining_time);
+ pterrain->mining_shield_incr,
+ pterrain->mining_time);
}
- } else if (terrains[i].mining_result != T_NONE) {
+ } else if (pterrain->mining_result != T_NONE) {
sprintf(buf, "%s / %d",
- terrains[terrains[i].mining_result].terrain_name,
- terrains[i].mining_time);
+ pterrain->mining_result->terrain_name,
+ pterrain->mining_time);
}
gtk_label_set_text(GTK_LABEL(help_tlabel[3][1]), buf);
- if (terrains[i].transform_result != T_NONE) {
+ if (pterrain->transform_result != T_NONE) {
sprintf(buf, "%s / %d",
- terrains[terrains[i].transform_result].terrain_name,
- terrains[i].transform_time);
+ pterrain->transform_result->terrain_name,
+ pterrain->transform_time);
} else {
strcpy(buf, "n/a");
}
gtk_label_set_text(GTK_LABEL(help_tlabel[3][4]), buf);
}
- helptext_terrain(buf, i, pitem->text);
+ helptext_terrain(buf, pterrain, pitem->text);
gtk_text_buffer_set_text(help_text, buf, -1);
gtk_widget_show(help_text_sw);
Index: client/gui-gtk-2.0/menu.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/menu.c,v
retrieving revision 1.80
diff -p -u -r1.80 menu.c
--- client/gui-gtk-2.0/menu.c 9 Jul 2005 17:46:07 -0000 1.80
+++ client/gui-gtk-2.0/menu.c 12 Jul 2005 15:43:25 -0000
@@ -1292,8 +1292,7 @@ void update_menus(void)
const char *transfmt = _("Transf_orm to %s");
char irrtext[128], mintext[128], transtext[128];
const char *roadtext;
- Terrain_type_id ttype;
- struct terrain * tinfo;
+ struct terrain *pterrain;
sz_strlcpy(irrtext, _("Build _Irrigation"));
sz_strlcpy(mintext, _("Build _Mine"));
@@ -1386,10 +1385,9 @@ void update_menus(void)
else
menus_rename("<main>/_Orders/Build _Road", _("Build _Road"));
- ttype = punit->tile->terrain;
- tinfo = get_terrain(ttype);
- if (tinfo->irrigation_result != T_NONE
- && tinfo->irrigation_result != ttype) {
+ pterrain = punit->tile->terrain;
+ if (pterrain->irrigation_result != T_NONE
+ && pterrain->irrigation_result != pterrain) {
my_snprintf(irrtext, sizeof(irrtext), irrfmt,
get_tile_change_menu_text(punit->tile,
ACTIVITY_IRRIGATE));
@@ -1398,13 +1396,13 @@ void update_menus(void)
TF_FARMLAND)) {
sz_strlcpy(irrtext, _("Bu_ild Farmland"));
}
- if (tinfo->mining_result != T_NONE
- && tinfo->mining_result != ttype) {
+ if (pterrain->mining_result != T_NONE
+ && pterrain->mining_result != pterrain) {
my_snprintf(mintext, sizeof(mintext), minfmt,
get_tile_change_menu_text(punit->tile, ACTIVITY_MINE));
}
- if (tinfo->transform_result != T_NONE
- && tinfo->transform_result != ttype) {
+ if (pterrain->transform_result != T_NONE
+ && pterrain->transform_result != pterrain) {
my_snprintf(transtext, sizeof(transtext), transfmt,
get_tile_change_menu_text(punit->tile,
ACTIVITY_TRANSFORM));
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.353
diff -p -u -r1.353 city.c
--- common/city.c 9 Jul 2005 17:46:08 -0000 1.353
+++ common/city.c 12 Jul 2005 15:43:26 -0000
@@ -573,22 +573,22 @@ static int base_get_output_tile(const st
int city_x, int city_y, bool is_celebrating,
Output_type_id otype)
{
- const struct terrain *ptype = get_terrain(ptile->terrain);
+ const struct terrain *pterrain = ptile->terrain;
struct tile tile;
int prod;
const bool auto_water = (pcity && is_city_center(city_x, city_y)
- && ptile->terrain == ptype->irrigation_result
+ && ptile->terrain == pterrain->irrigation_result
&& terrain_control.may_irrigate);
const struct output_type *output = &output_types[otype];
assert(otype >= 0 && otype < O_LAST);
if (tile_has_special(ptile, S_SPECIAL_1)) {
- prod = terrains[ptile->terrain].special[0].output[otype];
+ prod = pterrain->special[0].output[otype];
} else if (tile_has_special(ptile, S_SPECIAL_2)) {
- prod = terrains[ptile->terrain].special[1].output[otype];
+ prod = pterrain->special[1].output[otype];
} else {
- prod = terrains[ptile->terrain].output[otype];
+ prod = pterrain->output[otype];
}
/* create dummy tile which has the city center bonuses. */
@@ -607,12 +607,12 @@ static int base_get_output_tile(const st
switch (otype) {
case O_SHIELD:
if (contains_special(tile.special, S_MINE)) {
- prod += ptype->mining_shield_incr;
+ prod += pterrain->mining_shield_incr;
}
break;
case O_FOOD:
if (contains_special(tile.special, S_IRRIGATION)) {
- prod += ptype->irrigation_food_incr;
+ prod += pterrain->irrigation_food_incr;
}
break;
case O_TRADE:
@@ -620,7 +620,7 @@ static int base_get_output_tile(const st
prod += terrain_control.river_trade_incr;
}
if (contains_special(tile.special, S_ROAD)) {
- prod += ptype->road_trade_incr;
+ prod += pterrain->road_trade_incr;
}
break;
case O_GOLD:
Index: common/combat.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/combat.c,v
retrieving revision 1.58
diff -p -u -r1.58 combat.c
--- common/combat.c 9 Jul 2005 17:46:08 -0000 1.58
+++ common/combat.c 12 Jul 2005 15:43:26 -0000
@@ -81,8 +81,8 @@ bool can_unit_attack_unit_at_tile(const
const struct unit *pdefender,
const struct tile *dest_tile)
{
- Terrain_type_id fromtile = punit->tile->terrain;
- Terrain_type_id totile = dest_tile->terrain;
+ struct terrain *fromtile = punit->tile->terrain;
+ struct terrain *totile = dest_tile->terrain;
struct city *pcity = dest_tile->city;
/* 1. Can we attack _anything_ ? */
@@ -385,7 +385,7 @@ int get_defense_power(const struct unit
{
int db, power = base_get_defense_power(punit);
- db = 10 + get_terrain(punit->tile->terrain)->defense_bonus / 10;
+ db = 10 + punit->tile->terrain->defense_bonus / 10;
if (tile_has_special(punit->tile, S_RIVER)) {
db += (db * terrain_control.river_defense_bonus) / 100;
}
@@ -485,15 +485,15 @@ int get_virtual_defense_power(Unit_type_
bool fortified, int veteran)
{
int defensepower = unit_types[def_type].defense_strength;
- Terrain_type_id t = tile_get_terrain(ptile);
int db;
- if (unit_types[def_type].move_type == LAND_MOVING && is_ocean(t)) {
+ if (unit_types[def_type].move_type == LAND_MOVING
+ && is_ocean(ptile->terrain)) {
/* Ground units on ship doesn't defend. */
return 0;
}
- db = 10 + get_terrain(t)->defense_bonus / 10;
+ db = 10 + ptile->terrain->defense_bonus / 10;
if (tile_has_special(ptile, S_RIVER)) {
db += (db * terrain_control.river_defense_bonus) / 100;
}
Index: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.226
diff -p -u -r1.226 game.c
--- common/game.c 9 Jul 2005 17:46:08 -0000 1.226
+++ common/game.c 12 Jul 2005 15:43:26 -0000
@@ -572,9 +572,7 @@ void translate_data_names(void)
tthis->name = Q_(tthis->name_orig);
} impr_type_iterate_end;
- terrain_type_iterate(i) {
- struct terrain *tthis = &terrains[i];
-
+ terrain_type_iterate(tthis) {
tthis->terrain_name = ((strcmp(tthis->terrain_name_orig, "") != 0)
? Q_(tthis->terrain_name_orig) : "");
Index: common/map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.c,v
retrieving revision 1.231
diff -p -u -r1.231 map.c
--- common/map.c 9 Jul 2005 17:46:08 -0000 1.231
+++ common/map.c 12 Jul 2005 15:43:26 -0000
@@ -540,13 +540,7 @@ int map_distance(const struct tile *tile
*************************************************************************/
bool is_cardinally_adj_to_ocean(const struct tile *ptile)
{
- cardinal_adjc_iterate(ptile, tile1) {
- if (is_ocean(tile_get_terrain(tile1))) {
- return TRUE;
- }
- } cardinal_adjc_iterate_end;
-
- return FALSE;
+ return count_terrain_flag_near_tile(ptile, TRUE, FALSE, TER_OCEANIC) > 0;
}
/****************************************************************************
@@ -554,14 +548,8 @@ bool is_cardinally_adj_to_ocean(const st
****************************************************************************/
bool is_safe_ocean(const struct tile *ptile)
{
- adjc_iterate(ptile, tile1) {
- Terrain_type_id ter = tile_get_terrain(tile1);
- if (!terrain_has_flag(ter, TER_UNSAFE_COAST) && ter != T_UNKNOWN) {
- return TRUE;
- }
- } adjc_iterate_end;
-
- return FALSE;
+ return count_terrain_flag_near_tile(ptile, FALSE, TRUE,
+ TER_UNSAFE_COAST) < 100;
}
/***************************************************************
@@ -569,16 +557,20 @@ bool is_safe_ocean(const struct tile *pt
***************************************************************/
bool is_water_adjacent_to_tile(const struct tile *ptile)
{
- if (is_ocean(ptile->terrain)
- || tile_has_special(ptile, S_RIVER)
- || tile_has_special(ptile, S_IRRIGATION))
+ if (ptile->terrain != T_UNKNOWN
+ && (is_ocean(ptile->terrain)
+ || tile_has_special(ptile, S_RIVER)
+ || tile_has_special(ptile, S_IRRIGATION))) {
return TRUE;
+ }
cardinal_adjc_iterate(ptile, tile1) {
- if (is_ocean(tile1->terrain)
- || tile_has_special(tile1, S_RIVER)
- || tile_has_special(tile1, S_IRRIGATION))
+ if (ptile->terrain != T_UNKNOWN
+ && (is_ocean(tile1->terrain)
+ || tile_has_special(tile1, S_RIVER)
+ || tile_has_special(tile1, S_IRRIGATION))) {
return TRUE;
+ }
} cardinal_adjc_iterate_end;
return FALSE;
@@ -682,7 +674,7 @@ static int tile_move_cost_ptrs(struct un
}
}
- return(get_terrain(t2->terrain)->movement_cost*SINGLE_MOVE);
+ return t2->terrain->movement_cost * SINGLE_MOVE;
}
/****************************************************************************
Index: common/movement.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/movement.c,v
retrieving revision 1.12
diff -p -u -r1.12 movement.c
--- common/movement.c 30 Jun 2005 15:43:01 -0000 1.12
+++ common/movement.c 12 Jul 2005 15:43:26 -0000
@@ -183,13 +183,13 @@ bool can_unit_exist_at_tile(const struct
even on native terrain. All terrains are native to air units.
****************************************************************************/
bool is_native_terrain(const struct unit *punit,
- Terrain_type_id terrain)
+ const struct terrain *pterrain)
{
switch (unit_types[punit->type].move_type) {
case LAND_MOVING:
- return !is_ocean(terrain);
+ return !is_ocean(pterrain);
case SEA_MOVING:
- return is_ocean(terrain);
+ return is_ocean(pterrain);
default:
return TRUE;
}
Index: common/movement.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/movement.h,v
retrieving revision 1.6
diff -p -u -r1.6 movement.h
--- common/movement.h 28 Jun 2005 17:24:56 -0000 1.6
+++ common/movement.h 12 Jul 2005 15:43:26 -0000
@@ -31,7 +31,7 @@ bool is_heli_unittype(Unit_type_id id);
bool is_ground_unittype(Unit_type_id id);
bool is_native_terrain(const struct unit *punit,
- Terrain_type_id terrain);
+ const struct terrain *pterrain);
bool can_unit_exist_at_tile(const struct unit *punit, const struct tile
*ptile);
bool can_unit_survive_at_tile(const struct unit *punit,
const struct tile *ptile);
Index: common/requirements.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.c,v
retrieving revision 1.28
diff -p -u -r1.28 requirements.c
--- common/requirements.c 23 Jun 2005 08:01:09 -0000 1.28
+++ common/requirements.c 12 Jul 2005 15:43:27 -0000
@@ -204,7 +204,7 @@ struct req_source req_source_from_values
source.value.special = value;
return source;
case REQ_TERRAIN:
- source.value.terrain = value;
+ source.value.terrain = get_terrain(value);
return source;
case REQ_NATION:
source.value.nation = value;
@@ -260,7 +260,7 @@ void req_source_get_values(const struct
*value = source->value.special;
return;
case REQ_TERRAIN:
- *value = source->value.terrain;
+ *value = source->value.terrain->index;
return;
case REQ_NATION:
*value = source->value.nation;
@@ -657,7 +657,7 @@ static bool is_special_in_range(const st
****************************************************************************/
static bool is_terrain_in_range(const struct tile *target_tile,
enum req_range range, bool survives,
- Terrain_type_id terrain)
+ const struct terrain *pterrain)
{
if (!target_tile) {
return FALSE;
@@ -666,9 +666,9 @@ static bool is_terrain_in_range(const st
switch (range) {
case REQ_RANGE_LOCAL:
/* The requirement is filled if the tile has the terrain. */
- return target_tile->terrain == terrain;
+ return pterrain && target_tile->terrain == pterrain;
case REQ_RANGE_ADJACENT:
- return is_terrain_near_tile(target_tile, terrain);
+ return pterrain && is_terrain_near_tile(target_tile, pterrain);
case REQ_RANGE_CITY:
case REQ_RANGE_CONTINENT:
case REQ_RANGE_PLAYER:
Index: common/requirements.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.h,v
retrieving revision 1.19
diff -p -u -r1.19 requirements.h
--- common/requirements.h 11 May 2005 14:11:21 -0000 1.19
+++ common/requirements.h 12 Jul 2005 15:43:27 -0000
@@ -57,7 +57,7 @@ struct req_source {
int gov; /* source government */
Impr_type_id building; /* source building */
enum tile_special_type special; /* source special */
- Terrain_type_id terrain; /* source terrain type */
+ struct terrain *terrain; /* source terrain type */
Nation_type_id nation; /* source nation type */
Unit_type_id unittype; /* source unittype */
enum unit_flag_id unitflag; /* source unit flag */
Index: common/terrain.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/terrain.c,v
retrieving revision 1.25
diff -p -u -r1.25 terrain.c
--- common/terrain.c 9 Jul 2005 17:46:08 -0000 1.25
+++ common/terrain.c 12 Jul 2005 15:43:27 -0000
@@ -27,7 +27,7 @@
#include "support.h"
#include "terrain.h"
-struct terrain terrains[MAX_NUM_TERRAINS];
+static struct terrain civ_terrains[MAX_NUM_TERRAINS];
enum tile_special_type infrastructure_specials[] = {
S_ROAD,
@@ -47,44 +47,44 @@ void terrains_init(void)
{
int i;
- for (i = 0; i < ARRAY_SIZE(terrains); i++) {
- struct terrain *t = get_terrain(i);
-
- t->index = i;
+ for (i = 0; i < ARRAY_SIZE(civ_terrains); i++) {
+ /* Can't use get_terrain here because it does a bounds check. */
+ civ_terrains[i].index = i;
}
}
-/***************************************************************
-...
-***************************************************************/
+/****************************************************************************
+ Return the terrain for the given terrain index.
+****************************************************************************/
struct terrain *get_terrain(Terrain_type_id type)
{
- return &terrains[type];
+ if (type < 0 || type >= game.control.terrain_count) {
+ /* This isn't an error; some T_UNKNOWN callers depend on it. */
+ return NULL;
+ }
+ return &civ_terrains[type];
}
/****************************************************************************
Return the terrain type matching the name, or T_UNKNOWN if none matches.
****************************************************************************/
-Terrain_type_id get_terrain_by_name(const char *name)
+struct terrain *get_terrain_by_name(const char *name)
{
- Terrain_type_id tt;
-
- for (tt = T_FIRST; tt < T_COUNT; tt++) {
- if (0 == strcmp (terrains[tt].terrain_name, name)) {
- return tt;
+ terrain_type_iterate(pterrain) {
+ if (0 == strcmp(pterrain->terrain_name, name)) {
+ return pterrain;
}
- }
+ } terrain_type_iterate_end;
return T_UNKNOWN;
}
-/***************************************************************
-...
-***************************************************************/
-const char *get_terrain_name(Terrain_type_id type)
+/****************************************************************************
+ Return the name of the terrain.
+****************************************************************************/
+const char *get_terrain_name(const struct terrain *pterrain)
{
- assert(type < T_COUNT);
- return terrains[type].terrain_name;
+ return pterrain->terrain_name;
}
/****************************************************************************
@@ -118,31 +118,32 @@ enum terrain_flag_id terrain_flag_from_s
}
/****************************************************************************
- Return a random terrain that has the specified flag.
+ Return a random terrain that has the specified flag. Returns T_UNKNOWN if
+ there is no matching terrain.
****************************************************************************/
-Terrain_type_id get_flag_terrain(enum terrain_flag_id flag)
+struct terrain *get_flag_terrain(enum terrain_flag_id flag)
{
bool has_flag[T_COUNT];
int count = 0;
- terrain_type_iterate(t) {
- if ((has_flag[t] = terrain_has_flag(t, flag))) {
+ terrain_type_iterate(pterrain) {
+ if ((has_flag[pterrain->index] = terrain_has_flag(pterrain, flag))) {
count++;
}
} terrain_type_iterate_end;
count = myrand(count);
- terrain_type_iterate(t) {
- if (has_flag[t]) {
+ terrain_type_iterate(pterrain) {
+ if (has_flag[pterrain->index]) {
if (count == 0) {
- return t;
+ return pterrain;
}
count--;
}
} terrain_type_iterate_end;
die("Reached end of get_flag_terrain!");
- return T_NONE;
+ return T_UNKNOWN;
}
/****************************************************************************
@@ -150,11 +151,9 @@ Terrain_type_id get_flag_terrain(enum te
****************************************************************************/
void terrains_free(void)
{
- terrain_type_iterate(t) {
- struct terrain *p = get_terrain(t);
-
- free(p->helptext);
- p->helptext = NULL;
+ terrain_type_iterate(pterrain) {
+ free(pterrain->helptext);
+ pterrain->helptext = NULL;
} terrain_type_iterate_end;
}
@@ -185,10 +184,11 @@ void terrains_free(void)
/****************************************************************************
Returns TRUE iff any adjacent tile contains the given terrain.
****************************************************************************/
-bool is_terrain_near_tile(const struct tile *ptile, Terrain_type_id t)
+bool is_terrain_near_tile(const struct tile *ptile,
+ const struct terrain *pterrain)
{
adjc_iterate(ptile, adjc_tile) {
- if (adjc_tile->terrain == t) {
+ if (pterrain && adjc_tile->terrain == pterrain) {
return TRUE;
}
} adjc_iterate_end;
@@ -201,12 +201,12 @@ bool is_terrain_near_tile(const struct t
****************************************************************************/
int count_terrain_near_tile(const struct tile *ptile,
bool cardinal_only, bool percentage,
- Terrain_type_id t)
+ const struct terrain *pterrain)
{
int count = 0, total = 0;
variable_adjc_iterate(ptile, adjc_tile, cardinal_only) {
- if (tile_get_terrain(adjc_tile) == t) {
+ if (pterrain && tile_get_terrain(adjc_tile) == pterrain) {
count++;
}
total++;
@@ -228,7 +228,7 @@ int count_terrain_property_near_tile(con
int count = 0, total = 0;
variable_adjc_iterate(ptile, adjc_tile, cardinal_only) {
- if (get_terrain(adjc_tile->terrain)->property[prop] > 0) {
+ if (adjc_tile->terrain->property[prop] > 0) {
count++;
}
total++;
@@ -386,7 +386,8 @@ int count_terrain_flag_near_tile(const s
int count = 0, total = 0;
variable_adjc_iterate(ptile, adjc_tile, cardinal_only) {
- if (terrain_has_flag(tile_get_terrain(adjc_tile), flag)) {
+ if (adjc_tile->terrain != T_UNKNOWN
+ && terrain_has_flag(adjc_tile->terrain, flag)) {
count++;
}
total++;
Index: common/terrain.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/terrain.h,v
retrieving revision 1.38
diff -p -u -r1.38 terrain.h
--- common/terrain.h 9 Jul 2005 17:46:08 -0000 1.38
+++ common/terrain.h 12 Jul 2005 15:43:27 -0000
@@ -43,9 +43,8 @@ extern enum tile_special_type infrastruc
BV_DEFINE(bv_special, S_LAST);
-#define T_NONE (-3) /* A special flag meaning no terrain type. */
-#define T_ANY (-2) /* A special flag that matches "any" terrain type. */
-#define T_UNKNOWN (-1) /* An unknown terrain. */
+#define T_NONE (NULL) /* A special flag meaning no terrain type. */
+#define T_UNKNOWN (NULL) /* An unknown terrain. */
/* The first terrain value and number of base terrains. This is used in
* loops. T_COUNT may eventually be turned into a variable. */
@@ -127,15 +126,15 @@ struct terrain {
int road_trade_incr;
int road_time;
- Terrain_type_id irrigation_result;
+ struct terrain *irrigation_result;
int irrigation_food_incr;
int irrigation_time;
- Terrain_type_id mining_result;
+ struct terrain *mining_result;
int mining_shield_incr;
int mining_time;
- Terrain_type_id transform_result;
+ struct terrain *transform_result;
int transform_time;
int rail_time;
int airbase_time;
@@ -143,8 +142,9 @@ struct terrain {
int clean_pollution_time;
int clean_fallout_time;
- Terrain_type_id warmer_wetter_result, warmer_drier_result;
- Terrain_type_id cooler_wetter_result, cooler_drier_result;
+ /* May be NULL if the transformation is impossible. */
+ struct terrain *warmer_wetter_result, *warmer_drier_result;
+ struct terrain *cooler_wetter_result, *cooler_drier_result;
/* These are special properties of the terrain used by mapgen. Generally
* for each property, if a tile is deemed to have that property then
@@ -160,25 +160,24 @@ struct terrain {
char *helptext;
};
-extern struct terrain terrains[MAX_NUM_TERRAINS];
-
/* Terrain allocation functions. */
void terrains_init(void);
/* General terrain accessor functions. */
struct terrain *get_terrain(Terrain_type_id type);
-Terrain_type_id get_terrain_by_name(const char * name);
-const char *get_terrain_name(Terrain_type_id type);
+struct terrain *get_terrain_by_name(const char *name);
+const char *get_terrain_name(const struct terrain *pterrain);
enum terrain_flag_id terrain_flag_from_str(const char *s);
-#define terrain_has_flag(terr, flag) BV_ISSET(terrains[(terr)].flags, flag)
-Terrain_type_id get_flag_terrain(enum terrain_flag_id flag);
+#define terrain_has_flag(terr, flag) BV_ISSET((terr)->flags, flag)
+struct terrain *get_flag_terrain(enum terrain_flag_id flag);
void terrains_free(void);
/* Functions to operate on a general terrain type. */
-bool is_terrain_near_tile(const struct tile *ptile, Terrain_type_id t);
+bool is_terrain_near_tile(const struct tile *ptile,
+ const struct terrain *pterrain);
int count_terrain_near_tile(const struct tile *ptile,
bool cardinal_only, bool percentage,
- Terrain_type_id t);
+ const struct terrain *pterrain);
int count_terrain_property_near_tile(const struct tile *ptile,
bool cardinal_only, bool percentage,
enum mapgen_terrain_property prop);
@@ -212,17 +211,20 @@ enum tile_special_type get_infrastructur
enum tile_special_type get_preferred_pillage(bv_special pset);
/* Terrain-specific functions. */
-#define is_ocean(x) (terrain_has_flag((x), TER_OCEANIC))
+#define is_ocean(pterrain) (terrain_has_flag((pterrain), TER_OCEANIC))
#define is_ocean_near_tile(ptile) \
is_terrain_flag_near_tile(ptile, TER_OCEANIC)
#define count_ocean_near_tile(ptile, cardinal_only, percentage)
\
count_terrain_flag_near_tile(ptile, cardinal_only, percentage, TER_OCEANIC)
/* This iterator iterates over all terrain types. */
-#define terrain_type_iterate(id) \
+#define terrain_type_iterate(pterrain) \
{ \
- Terrain_type_id id; \
- for (id = T_FIRST; id < T_COUNT; id++) {
+ Terrain_type_id _index; \
+ \
+ for (_index = T_FIRST; _index < T_COUNT; _index++) { \
+ struct terrain *pterrain = get_terrain(_index);
+
#define terrain_type_iterate_end \
} \
Index: common/tile.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/tile.c,v
retrieving revision 1.8
diff -p -u -r1.8 tile.c
--- common/tile.c 9 Jul 2005 17:46:08 -0000 1.8
+++ common/tile.c 12 Jul 2005 15:43:27 -0000
@@ -57,7 +57,7 @@ void tile_set_city(struct tile *ptile, s
Return the terrain ID of the tile. Terrains are defined in the ruleset
(see terrain.h).
****************************************************************************/
-Terrain_type_id tile_get_terrain(const struct tile *ptile)
+struct terrain *tile_get_terrain(const struct tile *ptile)
{
return ptile->terrain;
}
@@ -65,9 +65,9 @@ Terrain_type_id tile_get_terrain(const s
/****************************************************************************
Set the terrain ID of the tile. See tile_get_terrain.
****************************************************************************/
-void tile_set_terrain(struct tile *ptile, Terrain_type_id ter)
+void tile_set_terrain(struct tile *ptile, struct terrain *pterrain)
{
- ptile->terrain = ter;
+ ptile->terrain = pterrain;
}
/****************************************************************************
@@ -164,23 +164,23 @@ int tile_activity_time(enum unit_activit
{
switch (activity) {
case ACTIVITY_POLLUTION:
- return terrains[ptile->terrain].clean_pollution_time * ACTIVITY_FACTOR;
+ return ptile->terrain->clean_pollution_time * ACTIVITY_FACTOR;
case ACTIVITY_ROAD:
- return terrains[ptile->terrain].road_time * ACTIVITY_FACTOR;
+ return ptile->terrain->road_time * ACTIVITY_FACTOR;
case ACTIVITY_MINE:
- return terrains[ptile->terrain].mining_time * ACTIVITY_FACTOR;
+ return ptile->terrain->mining_time * ACTIVITY_FACTOR;
case ACTIVITY_IRRIGATE:
- return terrains[ptile->terrain].irrigation_time * ACTIVITY_FACTOR;
+ return ptile->terrain->irrigation_time * ACTIVITY_FACTOR;
case ACTIVITY_FORTRESS:
- return terrains[ptile->terrain].fortress_time * ACTIVITY_FACTOR;
+ return ptile->terrain->fortress_time * ACTIVITY_FACTOR;
case ACTIVITY_RAILROAD:
- return terrains[ptile->terrain].rail_time * ACTIVITY_FACTOR;
+ return ptile->terrain->rail_time * ACTIVITY_FACTOR;
case ACTIVITY_TRANSFORM:
- return terrains[ptile->terrain].transform_time * ACTIVITY_FACTOR;
+ return ptile->terrain->transform_time * ACTIVITY_FACTOR;
case ACTIVITY_AIRBASE:
- return terrains[ptile->terrain].airbase_time * ACTIVITY_FACTOR;
+ return ptile->terrain->airbase_time * ACTIVITY_FACTOR;
case ACTIVITY_FALLOUT:
- return terrains[ptile->terrain].clean_fallout_time * ACTIVITY_FACTOR;
+ return ptile->terrain->clean_fallout_time * ACTIVITY_FACTOR;
default:
return 0;
}
@@ -212,10 +212,10 @@ static void tile_clear_dirtiness(struct
the tile (as will happen when mining/irrigation/transforming changes the
tile's terrain).
****************************************************************************/
-void tile_change_terrain(struct tile *ptile, Terrain_type_id type)
+void tile_change_terrain(struct tile *ptile, struct terrain *pterrain)
{
- tile_set_terrain(ptile, type);
- if (is_ocean(type)) {
+ tile_set_terrain(ptile, pterrain);
+ if (is_ocean(pterrain)) {
tile_clear_infrastructure(ptile);
tile_clear_dirtiness(ptile);
@@ -227,11 +227,11 @@ void tile_change_terrain(struct tile *pt
/* Clear mining/irrigation if resulting terrain type cannot support
* that feature. */
- if (terrains[type].mining_result != type) {
+ if (pterrain->mining_result != pterrain) {
tile_clear_special(ptile, S_MINE);
}
- if (terrains[type].irrigation_result != type) {
+ if (pterrain->irrigation_result != pterrain) {
tile_clear_special(ptile, S_IRRIGATION);
tile_clear_special(ptile, S_FARMLAND);
}
@@ -243,10 +243,10 @@ void tile_change_terrain(struct tile *pt
****************************************************************************/
static void tile_irrigate(struct tile *ptile)
{
- Terrain_type_id now, result;
+ struct terrain *now, *result;
now = ptile->terrain;
- result = terrains[now].irrigation_result;
+ result = now->irrigation_result;
if (now == result) {
if (tile_has_special(ptile, S_IRRIGATION)) {
@@ -266,10 +266,10 @@ static void tile_irrigate(struct tile *p
****************************************************************************/
static void tile_mine(struct tile *ptile)
{
- Terrain_type_id now, result;
+ struct terrain *now, *result;
now = ptile->terrain;
- result = terrains[now].mining_result;
+ result = now->mining_result;
if (now == result) {
tile_set_special(ptile, S_MINE);
@@ -286,10 +286,10 @@ static void tile_mine(struct tile *ptile
****************************************************************************/
static void tile_transform(struct tile *ptile)
{
- Terrain_type_id now, result;
+ struct terrain *now, *result;
now = ptile->terrain;
- result = terrains[now].transform_result;
+ result = now->transform_result;
if (result != T_NONE) {
tile_change_terrain(ptile, result);
@@ -378,7 +378,7 @@ const char *tile_get_info_text(const str
static char s[256];
bool first;
- sz_strlcpy(s, terrains[ptile->terrain].terrain_name);
+ sz_strlcpy(s, ptile->terrain->terrain_name);
if (tile_has_special(ptile, S_RIVER)) {
sz_strlcat(s, "/");
sz_strlcat(s, get_special_name(S_RIVER));
@@ -392,7 +392,7 @@ const char *tile_get_info_text(const str
} else {
sz_strlcat(s, "/");
}
- sz_strlcat(s, terrains[ptile->terrain].special[0].name);
+ sz_strlcat(s, ptile->terrain->special[0].name);
}
if (tile_has_special(ptile, S_SPECIAL_2)) {
if (first) {
@@ -401,7 +401,7 @@ const char *tile_get_info_text(const str
} else {
sz_strlcat(s, "/");
}
- sz_strlcat(s, terrains[ptile->terrain].special[1].name);
+ sz_strlcat(s, ptile->terrain->special[1].name);
}
if (!first) {
sz_strlcat(s, ")");
Index: common/tile.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/tile.h,v
retrieving revision 1.10
diff -p -u -r1.10 tile.h
--- common/tile.h 8 Jul 2005 03:31:18 -0000 1.10
+++ common/tile.h 12 Jul 2005 15:43:27 -0000
@@ -28,7 +28,7 @@ struct tile {
int x, y; /* Cartesian (map) coordinates of the tile. */
int nat_x, nat_y; /* Native coordinates of the tile. */
int index; /* Index coordinate of the tile. */
- Terrain_type_id terrain;
+ struct terrain *terrain; /* May be NULL for unknown tiles. */
bv_special special;
struct city *city; /* city standing on the tile, NULL if none */
struct unit_list *units;
@@ -53,8 +53,8 @@ struct player *tile_get_owner(const stru
void tile_set_owner(struct tile *ptile, struct player *pplayer);
struct city *tile_get_city(const struct tile *ptile);
void tile_set_city(struct tile *ptile, struct city *pcity);
-Terrain_type_id tile_get_terrain(const struct tile *ptile);
-void tile_set_terrain(struct tile *ptile, Terrain_type_id ter);
+struct terrain *tile_get_terrain(const struct tile *ptile);
+void tile_set_terrain(struct tile *ptile, struct terrain *pterrain);
bv_special tile_get_special(const struct tile *ptile);
bool tile_has_special(const struct tile *ptile,
enum tile_special_type to_test_for);
@@ -73,7 +73,7 @@ enum known_type tile_get_known(const str
int tile_activity_time(enum unit_activity activity,
const struct tile *ptile);
-void tile_change_terrain(struct tile *ptile, Terrain_type_id type);
+void tile_change_terrain(struct tile *ptile, struct terrain *pterrain);
bool tile_apply_activity(struct tile *ptile, Activity_type_id act);
const char *tile_get_info_text(const struct tile *ptile);
Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.244
diff -p -u -r1.244 unit.c
--- common/unit.c 9 Jul 2005 17:46:08 -0000 1.244
+++ common/unit.c 12 Jul 2005 15:43:27 -0000
@@ -731,7 +731,7 @@ bool can_unit_do_activity_targeted_at(co
const struct tile *ptile)
{
struct player *pplayer = unit_owner(punit);
- struct terrain *type = get_terrain(ptile->terrain);
+ struct terrain *pterrain = ptile->terrain;
switch(activity) {
case ACTIVITY_IDLE:
@@ -750,7 +750,7 @@ bool can_unit_do_activity_targeted_at(co
return (terrain_control.may_road
&& unit_flag(punit, F_SETTLERS)
&& !tile_has_special(ptile, S_ROAD)
- && type->road_time != 0
+ && pterrain->road_time != 0
&& (!tile_has_special(ptile, S_RIVER)
|| player_knows_techs_with_flag(pplayer, TF_BRIDGE)));
@@ -759,17 +759,17 @@ bool can_unit_do_activity_targeted_at(co
* *Do* allow it if they're transforming - the mine may survive */
if (terrain_control.may_mine
&& unit_flag(punit, F_SETTLERS)
- && ((ptile->terrain == type->mining_result
+ && ((ptile->terrain == pterrain->mining_result
&& !tile_has_special(ptile, S_MINE))
- || (ptile->terrain != type->mining_result
- && type->mining_result != T_NONE
+ || (ptile->terrain != pterrain->mining_result
+ && pterrain->mining_result != T_NONE
&& (!is_ocean(ptile->terrain)
- || is_ocean(type->mining_result)
+ || is_ocean(pterrain->mining_result)
|| can_reclaim_ocean(ptile))
&& (is_ocean(ptile->terrain)
- || !is_ocean(type->mining_result)
+ || !is_ocean(pterrain->mining_result)
|| can_channel_land(ptile))
- && (!is_ocean(type->mining_result)
+ && (!is_ocean(pterrain->mining_result)
|| !tile_get_city(ptile))))) {
unit_list_iterate(ptile->units, tunit) {
if (tunit->activity == ACTIVITY_IRRIGATE) {
@@ -789,17 +789,17 @@ bool can_unit_do_activity_targeted_at(co
&& (!tile_has_special(ptile, S_IRRIGATION)
|| (!tile_has_special(ptile, S_FARMLAND)
&& player_knows_techs_with_flag(pplayer, TF_FARMLAND)))
- && ((ptile->terrain == type->irrigation_result
+ && ((ptile->terrain == pterrain->irrigation_result
&& is_water_adjacent_to_tile(ptile))
- || (ptile->terrain != type->irrigation_result
- && type->irrigation_result != T_NONE
+ || (ptile->terrain != pterrain->irrigation_result
+ && pterrain->irrigation_result != T_NONE
&& (!is_ocean(ptile->terrain)
- || is_ocean(type->irrigation_result)
+ || is_ocean(pterrain->irrigation_result)
|| can_reclaim_ocean(ptile))
&& (is_ocean(ptile->terrain)
- || !is_ocean(type->irrigation_result)
+ || !is_ocean(pterrain->irrigation_result)
|| can_channel_land(ptile))
- && (!is_ocean(type->irrigation_result)
+ && (!is_ocean(pterrain->irrigation_result)
|| !tile_get_city(ptile))))) {
unit_list_iterate(ptile->units, tunit) {
if (tunit->activity == ACTIVITY_MINE) {
@@ -891,15 +891,15 @@ bool can_unit_do_activity_targeted_at(co
case ACTIVITY_TRANSFORM:
return (terrain_control.may_transform
- && type->transform_result != T_NONE
- && ptile->terrain != type->transform_result
+ && pterrain->transform_result != T_NONE
+ && ptile->terrain != pterrain->transform_result
&& (!is_ocean(ptile->terrain)
- || is_ocean(type->transform_result)
+ || is_ocean(pterrain->transform_result)
|| can_reclaim_ocean(ptile))
&& (is_ocean(ptile->terrain)
- || !is_ocean(type->transform_result)
+ || !is_ocean(pterrain->transform_result)
|| can_channel_land(ptile))
- && (!terrain_has_flag(type->transform_result, TER_NO_CITIES)
+ && (!terrain_has_flag(pterrain->transform_result, TER_NO_CITIES)
|| !(tile_get_city(ptile)))
&& unit_flag(punit, F_TRANSFORM));
Index: common/aicore/pf_tools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/pf_tools.c,v
retrieving revision 1.34
diff -p -u -r1.34 pf_tools.c
--- common/aicore/pf_tools.c 9 Jul 2005 17:46:09 -0000 1.34
+++ common/aicore/pf_tools.c 12 Jul 2005 15:43:27 -0000
@@ -122,7 +122,7 @@ static int normal_move_unit(const struct
const struct tile *ptile1,
struct pf_parameter *param)
{
- Terrain_type_id terrain1 = ptile1->terrain;
+ struct terrain *terrain1 = ptile1->terrain;
int move_cost;
if (is_ocean(terrain1)) {
@@ -137,7 +137,7 @@ static int normal_move_unit(const struct
|| is_non_allied_city_tile(ptile1, param->owner))) {
move_cost = PF_IMPOSSIBLE_MC;
} else {
- move_cost = get_terrain(terrain1)->movement_cost * SINGLE_MOVE;
+ move_cost = terrain1->movement_cost * SINGLE_MOVE;
}
} else {
move_cost = map_move_cost_ai(ptile, ptile1);
@@ -169,8 +169,7 @@ static int land_attack_move(const struct
/* Sea-to-Land. */
if (!is_non_allied_unit_tile(tgt_tile, param->owner)
&& !is_non_allied_city_tile(tgt_tile, param->owner)) {
- move_cost
- = get_terrain(tgt_tile->terrain)->movement_cost * SINGLE_MOVE;
+ move_cost = tgt_tile->terrain->movement_cost * SINGLE_MOVE;
} else if (BV_ISSET(param->unit_flags, F_MARINES)) {
/* Can attack!! */
move_cost = SINGLE_MOVE;
@@ -217,13 +216,13 @@ static int land_overlap_move(const struc
const struct tile *ptile1,
struct pf_parameter *param)
{
- Terrain_type_id terrain1 = ptile1->terrain;
+ struct terrain *terrain1 = ptile1->terrain;
int move_cost;
if (is_ocean(terrain1)) {
move_cost = SINGLE_MOVE;
} else if (is_ocean(ptile->terrain)) {
- move_cost = get_terrain(terrain1)->movement_cost * SINGLE_MOVE;
+ move_cost = terrain1->movement_cost * SINGLE_MOVE;
} else {
move_cost = map_move_cost_ai(ptile, ptile1);
}
@@ -240,14 +239,14 @@ static int reverse_move_unit(const struc
const struct tile *ptile,
struct pf_parameter *param)
{
- int terrain0 = tile_get_terrain(tile0);
- int terrain1 = ptile->terrain;
+ struct terrain *terrain0 = tile0->terrain;
+ struct terrain *terrain1 = ptile->terrain;
int move_cost = PF_IMPOSSIBLE_MC;
if (is_ocean(terrain1)) {
if (ground_unit_transporter_capacity(ptile, param->owner) > 0) {
/* Landing */
- move_cost = get_terrain(terrain0)->movement_cost * SINGLE_MOVE;
+ move_cost = terrain0->movement_cost * SINGLE_MOVE;
} else {
/* Nothing to land from */
move_cost = PF_IMPOSSIBLE_MC;
@@ -305,14 +304,14 @@ static int reverse_igter_move_unit(const
{
int move_cost;
- if (is_ocean(tile_get_terrain(ptile))) {
+ if (is_ocean(ptile->terrain)) {
if (ground_unit_transporter_capacity(ptile, param->owner) > 0) {
/* Landing */
move_cost = MOVE_COST_ROAD;
} else {
move_cost = PF_IMPOSSIBLE_MC;
}
- } else if (is_ocean(tile_get_terrain(tile0))) {
+ } else if (is_ocean(tile0->terrain)) {
/* Boarding */
move_cost = MOVE_COST_ROAD;
} else {
@@ -378,7 +377,7 @@ static int afraid_of_dark_forest(const s
enum known_type known,
struct pf_parameter *param)
{
- if (tile_get_terrain(ptile) == T_FOREST) {
+ if (ptile->terrain->index == T_FOREST) {
/* Willing to spend extra 2 turns to go around a forest tile */
return PF_TURN_FACTOR * 2;
}
Index: manual/civmanual.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/manual/civmanual.c,v
retrieving revision 1.13
diff -p -u -r1.13 civmanual.c
--- manual/civmanual.c 9 Jul 2005 17:46:09 -0000 1.13
+++ manual/civmanual.c 12 Jul 2005 15:43:27 -0000
@@ -225,38 +225,37 @@ static bool manual_command(void)
fprintf(doc, _("<th>Irrigation +food</th><th>Mining +shields</th>\n"));
fprintf(doc, _("<th>Transform to</th>"));
fprintf(doc, "</tr>\n");
- terrain_type_iterate(id) {
- struct terrain *ptype = get_terrain(id);
+ terrain_type_iterate(pterrain) {
int s;
- if (ptype->defense_bonus == 0) {
+ if (pterrain->defense_bonus == 0) {
/* Must be a disabled piece of terrain */
continue;
}
fprintf(doc, "<tr><td>%s%s%s %s</td>", IMAGE_BEGIN,
- ptype->graphic_str,
- IMAGE_END, get_terrain_name(id));
+ pterrain->graphic_str,
+ IMAGE_END, get_terrain_name(pterrain));
fprintf(doc, "<td>%d / %d / %d</td>",
- ptype->output[O_FOOD], ptype->output[O_SHIELD],
- ptype->output[O_TRADE]);
+ pterrain->output[O_FOOD], pterrain->output[O_SHIELD],
+ pterrain->output[O_TRADE]);
for (s = 0; s < MAX_NUM_SPECIALS; s++) {
fprintf(doc, "<td>%s%s%s %s</td>", IMAGE_BEGIN,
- ptype->special[s].graphic_str, IMAGE_END,
- ptype->special[s].name);
+ pterrain->special[s].graphic_str, IMAGE_END,
+ pterrain->special[s].name);
fprintf(doc, "<td>%d / %d / %d</td>",
- ptype->special[s].output[O_FOOD],
- ptype->special[s].output[O_SHIELD],
- ptype->special[s].output[O_TRADE]);
+ pterrain->special[s].output[O_FOOD],
+ pterrain->special[s].output[O_SHIELD],
+ pterrain->special[s].output[O_TRADE]);
}
- fprintf(doc, "<td>%d</td>\n", ptype->movement_cost);
+ fprintf(doc, "<td>%d</td>\n", pterrain->movement_cost);
fprintf(doc, "<td>%d0%%</td><td>%d</td><td>%d</td><td>%d</td>\n",
- ptype->defense_bonus, ptype->road_trade_incr,
- ptype->irrigation_food_incr, ptype->mining_shield_incr);
+ pterrain->defense_bonus, pterrain->road_trade_incr,
+ pterrain->irrigation_food_incr, pterrain->mining_shield_incr);
fprintf(doc, "<td>%s</td></tr>\n\n",
- get_terrain_name(ptype->transform_result));
+ get_terrain_name(pterrain->transform_result));
} terrain_type_iterate_end;
fprintf(doc, _("</table><br><br><br><table border=1>"));
fprintf(doc, _("<caption>Time to perform action</caption>"));
@@ -266,24 +265,23 @@ static bool manual_command(void)
fprintf(doc, _("<th>Airbase</th><th>Fortress</th>\n"));
fprintf(doc, _("<th>Clean pollution</th><th>Clean fallout</th>\n"));
fprintf(doc, _("<th>Transform</th></tr>\n"));
- terrain_type_iterate(id) {
- const char *name = get_terrain_name(id);
- struct terrain *ptype = get_terrain(id);
+ terrain_type_iterate(pterrain) {
+ const char *name = get_terrain_name(pterrain);
- if (ptype->terrain_name[0] == '\0') {
+ if (pterrain->terrain_name[0] == '\0') {
/* Must be a disabled piece of terrain */
continue;
}
fprintf(doc, "<tr><td>%s%s%s %s</td><td>%d</td>\n",
- IMAGE_BEGIN, ptype->graphic_str, IMAGE_END, name,
- ptype->road_time);
+ IMAGE_BEGIN, pterrain->graphic_str, IMAGE_END, name,
+ pterrain->road_time);
fprintf(doc, "<td>%d</td><td>%d</td><td>%d</td><td>%d</td>\n",
- ptype->irrigation_time, ptype->mining_time,
- ptype->rail_time, ptype->airbase_time);
+ pterrain->irrigation_time, pterrain->mining_time,
+ pterrain->rail_time, pterrain->airbase_time);
fprintf(doc, "<td>%d</td><td>%d</td><td>%d</td><td>%d</td>\n",
- ptype->fortress_time, ptype->clean_pollution_time,
- ptype->clean_fallout_time, ptype->transform_time);
+ pterrain->fortress_time, pterrain->clean_pollution_time,
+ pterrain->clean_fallout_time, pterrain->transform_time);
fprintf(doc, "</tr>\n\n");
} terrain_type_iterate_end;
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.332
diff -p -u -r1.332 citytools.c
--- server/citytools.c 4 Jul 2005 17:48:38 -0000 1.332
+++ server/citytools.c 12 Jul 2005 15:43:28 -0000
@@ -128,7 +128,6 @@ static int evaluate_city_name_priority(s
/* Lower values mean higher priority. */
float priority = (float)default_priority;
int goodness;
- Terrain_type_id type;
/* Increasing this value will increase the difference caused by
(non-)matching terrain. A matching terrain is mult_factor
@@ -183,16 +182,18 @@ static int evaluate_city_name_priority(s
priority *= mult_factor;
}
- for (type = T_FIRST; type < T_COUNT; type++) {
+ terrain_type_iterate(pterrain) {
/* Now we do the same for every available terrain. */
- goodness = is_terrain_near_tile(ptile, type) ?
- city_name->terrain[type] : -city_name->terrain[type];
+ goodness
+ = is_terrain_near_tile(ptile, pterrain)
+ ? city_name->terrain[pterrain->index]
+ : -city_name->terrain[pterrain->index];
if (goodness > 0) {
priority /= mult_factor;
} else if (goodness < 0) {
priority *= mult_factor;
}
- }
+ } terrain_type_iterate_end;
return (int)priority;
}
Index: server/gotohand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gotohand.c,v
retrieving revision 1.194
diff -p -u -r1.194 gotohand.c
--- server/gotohand.c 9 Jul 2005 17:46:09 -0000 1.194
+++ server/gotohand.c 12 Jul 2005 15:43:29 -0000
@@ -311,7 +311,9 @@ void really_generate_warmap(struct city
else
continue;
} else if (is_ocean(ptile->terrain)) {
- int base_cost = get_terrain(tile_get_terrain(tile1))->movement_cost *
SINGLE_MOVE;
+ int base_cost
+ = tile_get_terrain(tile1)->movement_cost * SINGLE_MOVE;
+
move_cost = igter ? MOVE_COST_ROAD : MIN(base_cost,
unit_move_rate(punit));
} else if (igter)
/* NOT c = 1 (Syela) [why not? - Thue] */
@@ -655,7 +657,8 @@ static bool find_the_shortest_path(struc
else
move_cost = 3;
} else if (is_ocean(psrctile->terrain)) {
- int base_cost = get_terrain(pdesttile->terrain)->movement_cost *
SINGLE_MOVE;
+ int base_cost = pdesttile->terrain->movement_cost * SINGLE_MOVE;
+
move_cost = igter ? 1 : MIN(base_cost, unit_move_rate(punit));
} else if (igter)
move_cost = (map_move_cost_ai(psrctile, pdesttile) != 0
Index: server/maphand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.c,v
retrieving revision 1.169
diff -p -u -r1.169 maphand.c
--- server/maphand.c 9 Jul 2005 17:46:09 -0000 1.169
+++ server/maphand.c 12 Jul 2005 15:43:29 -0000
@@ -65,7 +65,11 @@ static void assign_continent_flood(struc
if (tile_get_continent(ptile) != 0) {
return;
}
-
+
+ if (ptile->terrain == T_UNKNOWN) {
+ return;
+ }
+
if (skip_unsafe && terrain_has_flag(tile_get_terrain(ptile), TER_UNSAFE)) {
/* FIXME: This should check a specialized flag, not the TER_UNSAFE
* flag which may not even be present. */
@@ -103,7 +107,7 @@ static void recalculate_lake_surrounders
whole_map_iterate(ptile) {
Continent_id cont = tile_get_continent(ptile);
- if (!is_ocean(tile_get_terrain(ptile))) {
+ if (ptile->terrain != T_UNKNOWN && !is_ocean(tile_get_terrain(ptile))) {
adjc_iterate(ptile, tile2) {
Continent_id cont2 = tile_get_continent(tile2);
if (is_ocean(tile_get_terrain(tile2))) {
@@ -150,15 +154,19 @@ void assign_continent_numbers(bool skip_
/* Assign new numbers */
whole_map_iterate(ptile) {
- const Terrain_type_id ter = tile_get_terrain(ptile);
+ const struct terrain *pterrain = tile_get_terrain(ptile);
if (tile_get_continent(ptile) != 0) {
/* Already assigned. */
continue;
}
- if (!skip_unsafe || !terrain_has_flag(ter, TER_UNSAFE)) {
- if (!is_ocean(ter)) {
+ if (ptile->terrain == T_UNKNOWN) {
+ continue; /* Can't assign this. */
+ }
+
+ if (!skip_unsafe || !terrain_has_flag(pterrain, TER_UNSAFE)) {
+ if (!is_ocean(pterrain)) {
map.num_continents++;
assert(map.num_continents < MAP_NCONT);
assign_continent_flood(ptile, TRUE, map.num_continents, skip_unsafe);
@@ -209,15 +217,15 @@ void global_warming(int effect)
k = map_num_tiles();
while(effect > 0 && (k--) > 0) {
- Terrain_type_id old, new;
+ struct terrain *old, *new;
struct tile *ptile;
ptile = rand_map_pos();
old = tile_get_terrain(ptile);
if (is_terrain_ecologically_wet(ptile)) {
- new = get_terrain(old)->warmer_wetter_result;
+ new = old->warmer_wetter_result;
} else {
- new = get_terrain(old)->warmer_drier_result;
+ new = old->warmer_drier_result;
}
if (new != T_NONE && old != new) {
effect--;
@@ -251,15 +259,15 @@ void nuclear_winter(int effect)
k = map_num_tiles();
while(effect > 0 && (k--) > 0) {
- Terrain_type_id old, new;
+ struct terrain *old, *new;
struct tile *ptile;
ptile = rand_map_pos();
old = tile_get_terrain(ptile);
if (is_terrain_ecologically_wet(ptile)) {
- new = get_terrain(old)->cooler_wetter_result;
+ new = old->cooler_wetter_result;
} else {
- new = get_terrain(old)->cooler_drier_result;
+ new = old->cooler_drier_result;
}
if (new != T_NONE && old != new) {
effect--;
@@ -471,7 +479,7 @@ void send_tile_info(struct conn_list *de
}
if (!pplayer || map_is_known_and_seen(ptile, pplayer)) {
info.known = TILE_KNOWN;
- info.type = ptile->terrain;
+ info.type = ptile->terrain->index;
for (spe = 0; spe < S_LAST; spe++) {
info.special[spe] = BV_ISSET(ptile->special, spe);
}
@@ -481,8 +489,9 @@ void send_tile_info(struct conn_list *de
} else if (pplayer && map_is_known(ptile, pplayer)
&& map_get_seen(ptile, pplayer) == 0) {
struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
+
info.known = TILE_KNOWN_FOGGED;
- info.type = plrtile->terrain;
+ info.type = plrtile->terrain->index;
info.owner = plrtile->owner >= 0 ? plrtile->owner : MAP_TILE_OWNER_NULL;
for (spe = 0; spe < S_LAST; spe++) {
info.special[spe] = BV_ISSET(plrtile->special, spe);
@@ -522,7 +531,7 @@ static void send_tile_info_always(struct
if (!pplayer) {
/* Observer sees all. */
info.known=TILE_KNOWN;
- info.type = ptile->terrain;
+ info.type = ptile->terrain->index;
for (spe = 0; spe < S_LAST; spe++) {
info.special[spe] = BV_ISSET(ptile->special, spe);
}
@@ -536,7 +545,7 @@ static void send_tile_info_always(struct
info.known = TILE_KNOWN_FOGGED;
}
plrtile = map_get_player_tile(ptile, pplayer);
- info.type = plrtile->terrain;
+ info.type = plrtile->terrain->index;
for (spe = 0; spe < S_LAST; spe++) {
info.special[spe] = BV_ISSET(plrtile->special, spe);
}
@@ -544,7 +553,7 @@ static void send_tile_info_always(struct
} else {
/* Unknown (the client needs these sometimes to draw correctly). */
info.known = TILE_UNKNOWN;
- info.type = ptile->terrain;
+ info.type = ptile->terrain->index;
for (spe = 0; spe < S_LAST; spe++) {
info.special[spe] = BV_ISSET(ptile->special, spe);
}
@@ -1514,9 +1523,9 @@ static void ocean_to_land_fix_rivers(str
continent numbers.
**************************************************************************/
enum ocean_land_change check_terrain_ocean_land_change(struct tile *ptile,
- Terrain_type_id oldter)
+ struct terrain *oldter)
{
- Terrain_type_id newter = tile_get_terrain(ptile);
+ struct terrain *newter = tile_get_terrain(ptile);
enum ocean_land_change change_type = OLC_NONE;
if (is_ocean(oldter) && !is_ocean(newter)) {
Index: server/maphand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.h,v
retrieving revision 1.58
diff -p -u -r1.58 maphand.h
--- server/maphand.h 4 Jul 2005 17:48:38 -0000 1.58
+++ server/maphand.h 12 Jul 2005 15:43:29 -0000
@@ -39,7 +39,7 @@ struct dumb_city{
};
struct player_tile {
- Terrain_type_id terrain;
+ struct terrain *terrain; /* May be NULL for unknown tiles. */
bv_special special;
signed char owner;
unsigned short seen_count;
@@ -108,7 +108,7 @@ void map_update_borders_landmass_change(
void map_calculate_borders(void);
enum ocean_land_change check_terrain_ocean_land_change(struct tile *ptile,
- Terrain_type_id oldter);
+ struct terrain *oldter);
int get_continent_size(Continent_id id);
int get_ocean_size(Continent_id id);
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.271
diff -p -u -r1.271 ruleset.c
--- server/ruleset.c 9 Jul 2005 17:46:09 -0000 1.271
+++ server/ruleset.c 12 Jul 2005 15:43:30 -0000
@@ -72,8 +72,7 @@ static int lookup_city_cost(struct secti
const char *entry, const char *filename);
static char *lookup_helptext(struct section_file *file, char *prefix);
-static Terrain_type_id lookup_terrain(char *name,
- Terrain_type_id tthis);
+static struct terrain *lookup_terrain(char *name, struct terrain *tthis);
static void load_tech_names(struct section_file *file);
static void load_unit_names(struct section_file *file);
@@ -646,11 +645,8 @@ static char *lookup_helptext(struct sect
/**************************************************************************
Look up a terrain name in the tile_types array and return its index.
**************************************************************************/
-static Terrain_type_id lookup_terrain(char *name,
- Terrain_type_id tthis)
+static struct terrain *lookup_terrain(char *name, struct terrain *tthis)
{
- Terrain_type_id i;
-
if (*name == '\0' || (0 == strcmp(name, "none"))
|| (0 == strcmp(name, "no"))) {
return T_NONE;
@@ -658,15 +654,15 @@ static Terrain_type_id lookup_terrain(ch
return (tthis);
}
- for (i = T_FIRST; i < T_COUNT; i++) {
- if (0 == strcmp(name, terrains[i].terrain_name)) {
- return i;
+ terrain_type_iterate(pterrain) {
+ if (0 == strcmp(name, pterrain->terrain_name)) {
+ return pterrain;
}
- }
+ } terrain_type_iterate_end;
/* TRANS: message for an obscure ruleset error. */
freelog(LOG_ERROR, _("Unknown terrain %s in entry %s."),
- name, terrains[tthis].terrain_name);
+ name, tthis->terrain_name);
return T_NONE;
}
@@ -1402,14 +1398,15 @@ static void load_terrain_names(struct se
}
game.control.terrain_count = nval;
- terrain_type_iterate(i) {
- char *name = secfile_lookup_str(file, "%s.terrain_name", sec[i]);
-
- name_strlcpy(terrains[i].terrain_name_orig, name);
- if (0 == strcmp(terrains[i].terrain_name_orig, "unused")) {
- terrains[i].terrain_name_orig[0] = '\0';
+ terrain_type_iterate(pterrain) {
+ char *name = secfile_lookup_str(file, "%s.terrain_name",
+ sec[pterrain->index]);
+
+ name_strlcpy(pterrain->terrain_name_orig, name);
+ if (0 == strcmp(pterrain->terrain_name_orig, "unused")) {
+ pterrain->terrain_name_orig[0] = '\0';
}
- terrains[i].terrain_name = terrains[i].terrain_name_orig;
+ pterrain->terrain_name = pterrain->terrain_name_orig;
} terrain_type_iterate_end;
free(sec);
@@ -1490,137 +1487,147 @@ static void load_ruleset_terrain(struct
/* terrain details */
- terrain_type_iterate(i) {
- struct terrain *t = &(terrains[i]);
- char **slist;
-
- sz_strlcpy(t->graphic_str,
- secfile_lookup_str(file,"%s.graphic", sec[i]));
- sz_strlcpy(t->graphic_alt,
- secfile_lookup_str(file,"%s.graphic_alt", sec[i]));
-
- t->identifier = secfile_lookup_str(file, "%s.identifier", sec[i])[0];
- for (j = T_FIRST; j < i; j++) {
- if (t->identifier == terrains[j].identifier) {
- freelog(LOG_FATAL,
- /* TRANS: message for an obscure ruleset error. */
- _("Terrains %s and %s have the same identifier."),
- t->terrain_name, terrains[j].terrain_name);
- exit(EXIT_FAILURE);
- }
- }
- if (t->identifier == UNKNOWN_TERRAIN_IDENTIFIER) {
- /* TRANS: message for an obscure ruleset error. */
- freelog(LOG_FATAL, _("'%c' cannot be used as a terrain identifier; "
- "it is reserved."), UNKNOWN_TERRAIN_IDENTIFIER);
+ terrain_type_iterate(pterrain) {
+ char **slist;
+ const int i = pterrain->index;
+
+ sz_strlcpy(pterrain->graphic_str,
+ secfile_lookup_str(file,"%s.graphic", sec[i]));
+ sz_strlcpy(pterrain->graphic_alt,
+ secfile_lookup_str(file,"%s.graphic_alt", sec[i]));
+
+ pterrain->identifier
+ = secfile_lookup_str(file, "%s.identifier", sec[i])[0];
+ for (j = T_FIRST; j < i; j++) {
+ if (pterrain->identifier == get_terrain(j)->identifier) {
+ freelog(LOG_FATAL,
+ /* TRANS: message for an obscure ruleset error. */
+ _("Terrains %s and %s have the same identifier."),
+ pterrain->terrain_name, get_terrain(j)->terrain_name);
exit(EXIT_FAILURE);
}
+ }
+ if (pterrain->identifier == UNKNOWN_TERRAIN_IDENTIFIER) {
+ /* TRANS: message for an obscure ruleset error. */
+ freelog(LOG_FATAL, _("'%c' cannot be used as a terrain identifier; "
+ "it is reserved."), UNKNOWN_TERRAIN_IDENTIFIER);
+ exit(EXIT_FAILURE);
+ }
+
+ pterrain->movement_cost
+ = secfile_lookup_int(file, "%s.movement_cost", sec[i]);
+ pterrain->defense_bonus
+ = secfile_lookup_int(file, "%s.defense_bonus", sec[i]);
- t->movement_cost = secfile_lookup_int(file, "%s.movement_cost", sec[i]);
- t->defense_bonus = secfile_lookup_int(file, "%s.defense_bonus", sec[i]);
+ output_type_iterate(o) {
+ pterrain->output[o]
+ = secfile_lookup_int_default(file, 0, "%s.%s", sec[i],
+ get_output_identifier(o));
+ } output_type_iterate_end;
+ for (j = 0; j < MAX_NUM_SPECIALS; j++) {
+ char *name = secfile_lookup_str(file, "%s.special_%d_name",
+ sec[i], j + 1);
+
+ name_strlcpy(pterrain->special[j].name_orig, name);
+ if (0 == strcmp(pterrain->special[j].name_orig, "none")) {
+ pterrain->special[j].name_orig[0] = '\0';
+ }
+ pterrain->special[j].name = pterrain->special[j].name_orig;
output_type_iterate(o) {
- t->output[o] = secfile_lookup_int_default(file, 0, "%s.%s", sec[i],
- get_output_identifier(o));
+ pterrain->special[j].output[o]
+ = secfile_lookup_int_default(file, 0, "%s.%s_special_%d", sec[i],
+ get_output_identifier(o), j + 1);
} output_type_iterate_end;
- for (j = 0; j < MAX_NUM_SPECIALS; j++) {
- char *name = secfile_lookup_str(file, "%s.special_%d_name",
- sec[i], j + 1);
-
- name_strlcpy(t->special[j].name_orig, name);
- if (0 == strcmp(t->special[j].name_orig, "none")) {
- t->special[j].name_orig[0] = '\0';
- }
- t->special[j].name = t->special[j].name_orig;
- output_type_iterate(o) {
- t->special[j].output[o]
- = secfile_lookup_int_default(file, 0, "%s.%s_special_%d", sec[i],
- get_output_identifier(o), j + 1);
- } output_type_iterate_end;
-
- sz_strlcpy(t->special[j].graphic_str,
- secfile_lookup_str(file,"%s.graphic_special_%d",
- sec[i], j+1));
- sz_strlcpy(t->special[j].graphic_alt,
- secfile_lookup_str(file,"%s.graphic_special_%da",
- sec[i], j+1));
- }
-
- t->road_trade_incr =
- secfile_lookup_int(file, "%s.road_trade_incr", sec[i]);
- t->road_time = secfile_lookup_int(file, "%s.road_time", sec[i]);
-
- t->irrigation_result =
- lookup_terrain(secfile_lookup_str(file, "%s.irrigation_result",
sec[i]), i);
- t->irrigation_food_incr =
- secfile_lookup_int(file, "%s.irrigation_food_incr", sec[i]);
- t->irrigation_time = secfile_lookup_int(file, "%s.irrigation_time",
sec[i]);
-
- t->mining_result =
- lookup_terrain(secfile_lookup_str(file, "%s.mining_result", sec[i]), i);
- t->mining_shield_incr =
- secfile_lookup_int(file, "%s.mining_shield_incr", sec[i]);
- t->mining_time = secfile_lookup_int(file, "%s.mining_time", sec[i]);
-
- t->transform_result =
- lookup_terrain(secfile_lookup_str(file, "%s.transform_result", sec[i]),
i);
- t->transform_time = secfile_lookup_int(file, "%s.transform_time",
sec[i]);
- t->rail_time =
- secfile_lookup_int_default(file, 3, "%s.rail_time", sec[i]);
- t->airbase_time =
- secfile_lookup_int_default(file, 3, "%s.airbase_time", sec[i]);
- t->fortress_time =
- secfile_lookup_int_default(file, 3, "%s.fortress_time", sec[i]);
- t->clean_pollution_time =
- secfile_lookup_int_default(file, 3, "%s.clean_pollution_time",
sec[i]);
- t->clean_fallout_time =
- secfile_lookup_int_default(file, 3, "%s.clean_fallout_time", sec[i]);
-
- t->warmer_wetter_result
- = lookup_terrain(secfile_lookup_str(file, "%s.warmer_wetter_result",
- sec[i]), i);
- t->warmer_drier_result
- = lookup_terrain(secfile_lookup_str(file, "%s.warmer_drier_result",
- sec[i]), i);
- t->cooler_wetter_result
- = lookup_terrain(secfile_lookup_str(file, "%s.cooler_wetter_result",
- sec[i]), i);
- t->cooler_drier_result
- = lookup_terrain(secfile_lookup_str(file, "%s.cooler_drier_result",
- sec[i]), i);
-
- slist = secfile_lookup_str_vec(file, &nval, "%s.flags", sec[i]);
- BV_CLR_ALL(t->flags);
- for (j = 0; j < nval; j++) {
- const char *sval = slist[j];
- enum terrain_flag_id flag = terrain_flag_from_str(sval);
-
- if (flag == TER_LAST) {
- /* TRANS: message for an obscure ruleset error. */
- freelog(LOG_FATAL, _("Terrain %s has unknown flag %s"),
- t->terrain_name, sval);
- exit(EXIT_FAILURE);
- } else {
- BV_SET(t->flags, flag);
- }
- }
- free(slist);
+ sz_strlcpy(pterrain->special[j].graphic_str,
+ secfile_lookup_str(file,"%s.graphic_special_%d",
+ sec[i], j+1));
+ sz_strlcpy(pterrain->special[j].graphic_alt,
+ secfile_lookup_str(file,"%s.graphic_special_%da",
+ sec[i], j+1));
+ }
+
+ pterrain->road_trade_incr
+ = secfile_lookup_int(file, "%s.road_trade_incr", sec[i]);
+ pterrain->road_time = secfile_lookup_int(file, "%s.road_time", sec[i]);
+
+ pterrain->irrigation_result
+ = lookup_terrain(secfile_lookup_str(file, "%s.irrigation_result",
+ sec[i]), pterrain);
+ pterrain->irrigation_food_incr
+ = secfile_lookup_int(file, "%s.irrigation_food_incr", sec[i]);
+ pterrain->irrigation_time
+ = secfile_lookup_int(file, "%s.irrigation_time", sec[i]);
+
+ pterrain->mining_result
+ = lookup_terrain(secfile_lookup_str(file, "%s.mining_result",
+ sec[i]), pterrain);
+ pterrain->mining_shield_incr
+ = secfile_lookup_int(file, "%s.mining_shield_incr", sec[i]);
+ pterrain->mining_time
+ = secfile_lookup_int(file, "%s.mining_time", sec[i]);
+
+ pterrain->transform_result
+ = lookup_terrain(secfile_lookup_str(file, "%s.transform_result",
+ sec[i]), pterrain);
+ pterrain->transform_time
+ = secfile_lookup_int(file, "%s.transform_time", sec[i]);
+ pterrain->rail_time
+ = secfile_lookup_int_default(file, 3, "%s.rail_time", sec[i]);
+ pterrain->airbase_time
+ = secfile_lookup_int_default(file, 3, "%s.airbase_time", sec[i]);
+ pterrain->fortress_time
+ = secfile_lookup_int_default(file, 3, "%s.fortress_time", sec[i]);
+ pterrain->clean_pollution_time
+ = secfile_lookup_int_default(file, 3, "%s.clean_pollution_time", sec[i]);
+ pterrain->clean_fallout_time
+ = secfile_lookup_int_default(file, 3, "%s.clean_fallout_time", sec[i]);
+
+ pterrain->warmer_wetter_result
+ = lookup_terrain(secfile_lookup_str(file, "%s.warmer_wetter_result",
+ sec[i]), pterrain);
+ pterrain->warmer_drier_result
+ = lookup_terrain(secfile_lookup_str(file, "%s.warmer_drier_result",
+ sec[i]), pterrain);
+ pterrain->cooler_wetter_result
+ = lookup_terrain(secfile_lookup_str(file, "%s.cooler_wetter_result",
+ sec[i]), pterrain);
+ pterrain->cooler_drier_result
+ = lookup_terrain(secfile_lookup_str(file, "%s.cooler_drier_result",
+ sec[i]), pterrain);
+
+ slist = secfile_lookup_str_vec(file, &nval, "%s.flags", sec[i]);
+ BV_CLR_ALL(pterrain->flags);
+ for (j = 0; j < nval; j++) {
+ const char *sval = slist[j];
+ enum terrain_flag_id flag = terrain_flag_from_str(sval);
- for (j = 0; j < MG_LAST; j++) {
- const char *mg_names[] = {
- "mountainous", "green", "foliage",
- "tropical", "temperate", "cold", "frozen",
- "wet", "dry", "ocean_depth"
- };
- assert(ARRAY_SIZE(mg_names) == MG_LAST);
-
- t->property[j] = secfile_lookup_int_default(file, 0,
- "%s.property_%s",
- sec[i], mg_names[j]);
+ if (flag == TER_LAST) {
+ /* TRANS: message for an obscure ruleset error. */
+ freelog(LOG_FATAL, _("Terrain %s has unknown flag %s"),
+ pterrain->terrain_name, sval);
+ exit(EXIT_FAILURE);
+ } else {
+ BV_SET(pterrain->flags, flag);
}
-
- t->helptext = lookup_helptext(file, sec[i]);
+ }
+ free(slist);
+
+ for (j = 0; j < MG_LAST; j++) {
+ const char *mg_names[] = {
+ "mountainous", "green", "foliage",
+ "tropical", "temperate", "cold", "frozen",
+ "wet", "dry", "ocean_depth"
+ };
+ assert(ARRAY_SIZE(mg_names) == MG_LAST);
+
+ pterrain->property[j] = secfile_lookup_int_default(file, 0,
+ "%s.property_%s",
+ sec[i], mg_names[j]);
+ }
+
+ pterrain->helptext = lookup_helptext(file, sec[i]);
} terrain_type_iterate_end;
free(sec);
@@ -1979,9 +1986,8 @@ static struct city_name* load_city_name_
} else {
/* "handled" tracks whether we find a match (for error handling) */
bool handled = FALSE;
- Terrain_type_id type;
-
- for (type = T_FIRST; type < T_COUNT && !handled; type++) {
+
+ terrain_type_iterate(pterrain) {
/*
* Note that at this time (before a call to
* translate_data_names) the terrain_name fields contains an
@@ -1989,11 +1995,12 @@ static struct city_name* load_city_name_
* However this is not a problem because we take care of rivers
* separately.
*/
- if (mystrcasecmp(name, terrains[type].terrain_name) == 0) {
- city_names[j].terrain[type] = setting;
+ if (mystrcasecmp(name, pterrain->terrain_name) == 0) {
+ city_names[j].terrain[pterrain->index] = setting;
handled = TRUE;
+ break;
}
- }
+ } terrain_type_iterate_end;
if (!handled) {
freelog(LOG_ERROR, "Unreadable terrain description %s "
"in city name ruleset \"%s%s\" - skipping it.",
@@ -2772,61 +2779,68 @@ static void send_ruleset_terrain(struct
lsend_packet_ruleset_terrain_control(dest, &terrain_control);
- terrain_type_iterate(i) {
- struct terrain *t = &(terrains[i]);
+ terrain_type_iterate(pterrain) {
+ const int i = pterrain->index;
- packet.id = i;
-
- sz_strlcpy(packet.terrain_name, t->terrain_name_orig);
- sz_strlcpy(packet.graphic_str, t->graphic_str);
- sz_strlcpy(packet.graphic_alt, t->graphic_alt);
+ packet.id = i;
- packet.movement_cost = t->movement_cost;
- packet.defense_bonus = t->defense_bonus;
+ sz_strlcpy(packet.terrain_name, pterrain->terrain_name_orig);
+ sz_strlcpy(packet.graphic_str, pterrain->graphic_str);
+ sz_strlcpy(packet.graphic_alt, pterrain->graphic_alt);
- output_type_iterate(o) {
- packet.output[o] = t->output[o];
- packet.output_special_1[o] = t->special[0].output[o];
- packet.output_special_2[o] = t->special[1].output[o];
- } output_type_iterate_end;
+ packet.movement_cost = pterrain->movement_cost;
+ packet.defense_bonus = pterrain->defense_bonus;
- sz_strlcpy(packet.special_1_name, t->special[0].name_orig);
- sz_strlcpy(packet.special_2_name, t->special[1].name_orig);
+ output_type_iterate(o) {
+ packet.output[o] = pterrain->output[o];
+ packet.output_special_1[o] = pterrain->special[0].output[o];
+ packet.output_special_2[o] = pterrain->special[1].output[o];
+ } output_type_iterate_end;
- sz_strlcpy(packet.graphic_str_special_1, t->special[0].graphic_str);
- sz_strlcpy(packet.graphic_alt_special_1, t->special[0].graphic_alt);
+ sz_strlcpy(packet.special_1_name, pterrain->special[0].name_orig);
+ sz_strlcpy(packet.special_2_name, pterrain->special[1].name_orig);
- sz_strlcpy(packet.graphic_str_special_2, t->special[1].graphic_str);
- sz_strlcpy(packet.graphic_alt_special_2, t->special[1].graphic_alt);
+ sz_strlcpy(packet.graphic_str_special_1,
+ pterrain->special[0].graphic_str);
+ sz_strlcpy(packet.graphic_alt_special_1,
+ pterrain->special[0].graphic_alt);
+
+ sz_strlcpy(packet.graphic_str_special_2,
+ pterrain->special[1].graphic_str);
+ sz_strlcpy(packet.graphic_alt_special_2,
+ pterrain->special[1].graphic_alt);
+
+ packet.road_trade_incr = pterrain->road_trade_incr;
+ packet.road_time = pterrain->road_time;
+
+ packet.irrigation_result = (pterrain->irrigation_result
+ ? pterrain->irrigation_result->index : -1);
+ packet.irrigation_food_incr = pterrain->irrigation_food_incr;
+ packet.irrigation_time = pterrain->irrigation_time;
+
+ packet.mining_result = (pterrain->mining_result
+ ? pterrain->mining_result->index : -1);
+ packet.mining_shield_incr = pterrain->mining_shield_incr;
+ packet.mining_time = pterrain->mining_time;
+
+ packet.transform_result = (pterrain->transform_result
+ ? pterrain->transform_result->index : -1);
+ packet.transform_time = pterrain->transform_time;
+ packet.rail_time = pterrain->rail_time;
+ packet.airbase_time = pterrain->airbase_time;
+ packet.fortress_time = pterrain->fortress_time;
+ packet.clean_pollution_time = pterrain->clean_pollution_time;
+ packet.clean_fallout_time = pterrain->clean_fallout_time;
- packet.road_trade_incr = t->road_trade_incr;
- packet.road_time = t->road_time;
-
- packet.irrigation_result = t->irrigation_result;
- packet.irrigation_food_incr = t->irrigation_food_incr;
- packet.irrigation_time = t->irrigation_time;
-
- packet.mining_result = t->mining_result;
- packet.mining_shield_incr = t->mining_shield_incr;
- packet.mining_time = t->mining_time;
-
- packet.transform_result = t->transform_result;
- packet.transform_time = t->transform_time;
- packet.rail_time = t->rail_time;
- packet.airbase_time = t->airbase_time;
- packet.fortress_time = t->fortress_time;
- packet.clean_pollution_time = t->clean_pollution_time;
- packet.clean_fallout_time = t->clean_fallout_time;
+ packet.flags = pterrain->flags;
- packet.flags = t->flags;
+ if (pterrain->helptext) {
+ sz_strlcpy(packet.helptext, pterrain->helptext);
+ } else {
+ packet.helptext[0] = '\0';
+ }
- if (t->helptext) {
- sz_strlcpy(packet.helptext, t->helptext);
- } else {
- packet.helptext[0] = '\0';
- }
-
- lsend_packet_ruleset_terrain(dest, &packet);
+ lsend_packet_ruleset_terrain(dest, &packet);
} terrain_type_iterate_end;
}
Index: server/sanitycheck.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sanitycheck.c,v
retrieving revision 1.69
diff -p -u -r1.69 sanitycheck.c
--- server/sanitycheck.c 9 Jul 2005 17:46:09 -0000 1.69
+++ server/sanitycheck.c 12 Jul 2005 15:43:30 -0000
@@ -55,7 +55,7 @@
static void check_specials(void)
{
whole_map_iterate(ptile) {
- Terrain_type_id terrain = tile_get_terrain(ptile);
+ const struct terrain *pterrain = tile_get_terrain(ptile);
bv_special special = tile_get_special(ptile);
if (contains_special(special, S_RAILROAD))
@@ -65,12 +65,14 @@ static void check_specials(void)
if (contains_special(special, S_SPECIAL_1))
SANITY_CHECK(!contains_special(special, S_SPECIAL_2));
- if (contains_special(special, S_MINE))
- SANITY_CHECK(get_terrain(terrain)->mining_result == terrain);
- if (contains_special(special, S_IRRIGATION))
- SANITY_CHECK(get_terrain(terrain)->irrigation_result == terrain);
+ if (contains_special(special, S_MINE)) {
+ SANITY_CHECK(pterrain->mining_result == pterrain);
+ }
+ if (contains_special(special, S_IRRIGATION)) {
+ SANITY_CHECK(pterrain->irrigation_result == pterrain);
+ }
- SANITY_CHECK(terrain >= T_FIRST && terrain < T_COUNT);
+ SANITY_CHECK(pterrain->index >= T_FIRST && pterrain->index < T_COUNT);
} whole_map_iterate_end;
}
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.261
diff -p -u -r1.261 savegame.c
--- server/savegame.c 10 Jul 2005 16:03:11 -0000 1.261
+++ server/savegame.c 12 Jul 2005 15:43:30 -0000
@@ -229,14 +229,14 @@ static int ascii_hex2bin(char ch, int ha
Dereferences the terrain character. See terrains[].identifier
example: char2terrain('a') => T_ARCTIC
****************************************************************************/
-static Terrain_type_id char2terrain(char ch)
+static struct terrain *char2terrain(char ch)
{
if (ch == UNKNOWN_TERRAIN_IDENTIFIER) {
return T_UNKNOWN;
}
- terrain_type_iterate(id) {
- if (terrains[id].identifier == ch) {
- return id;
+ terrain_type_iterate(pterrain) {
+ if (pterrain->identifier == ch) {
+ return pterrain;
}
} terrain_type_iterate_end;
@@ -249,13 +249,12 @@ static Terrain_type_id char2terrain(char
References the terrain character. See terrains[].identifier
example: terrain2char(T_ARCTIC) => 'a'
****************************************************************************/
-static char terrain2char(Terrain_type_id terr)
+static char terrain2char(const struct terrain *pterrain)
{
- if (terr == T_UNKNOWN) {
+ if (pterrain == T_UNKNOWN) {
return UNKNOWN_TERRAIN_IDENTIFIER;
} else {
- assert(terr >= T_FIRST && terr < T_COUNT);
- return terrains[terr].identifier;
+ return pterrain->identifier;
}
}
Index: server/settlers.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/settlers.c,v
retrieving revision 1.243
diff -p -u -r1.243 settlers.c
--- server/settlers.c 9 Jul 2005 17:46:09 -0000 1.243
+++ server/settlers.c 12 Jul 2005 15:43:31 -0000
@@ -232,15 +232,12 @@ static int ai_calc_fallout(struct city *
**************************************************************************/
static bool is_wet(struct player *pplayer, struct tile *ptile)
{
- Terrain_type_id terrain;
-
/* FIXME: this should check a handicap. */
if (!pplayer->ai.control && !map_is_known(ptile, pplayer)) {
return FALSE;
}
- terrain = tile_get_terrain(ptile);
- if (is_ocean(terrain)) {
+ if (is_ocean(ptile->terrain)) {
/* TODO: perhaps salt water should not be usable for irrigation? */
return TRUE;
}
@@ -293,10 +290,9 @@ static int ai_calc_irrigate(struct city
int city_x, int city_y, struct tile *ptile)
{
int goodness;
- Terrain_type_id old_terrain = ptile->terrain;
+ struct terrain *old_terrain = ptile->terrain;
bv_special old_special = ptile->special;
- struct terrain *type = get_terrain(old_terrain);
- Terrain_type_id new_terrain = type->irrigation_result;
+ struct terrain *new_terrain = old_terrain->irrigation_result;
if (old_terrain != new_terrain && new_terrain != T_NONE) {
/* Irrigation would change the terrain type, clearing the mine
@@ -358,10 +354,9 @@ static int ai_calc_mine(struct city *pci
int city_x, int city_y, struct tile *ptile)
{
int goodness;
- Terrain_type_id old_terrain = ptile->terrain;
+ struct terrain *old_terrain = ptile->terrain;
bv_special old_special = ptile->special;
- struct terrain *type = get_terrain(old_terrain);
- Terrain_type_id new_terrain = type->mining_result;
+ struct terrain *new_terrain = old_terrain->mining_result;
if (old_terrain != new_terrain && new_terrain != T_NONE) {
/* Mining would change the terrain type, clearing the irrigation
@@ -410,10 +405,9 @@ static int ai_calc_transform(struct city
int city_x, int city_y, struct tile *ptile)
{
int goodness;
- Terrain_type_id old_terrain = ptile->terrain;
+ struct terrain *old_terrain = ptile->terrain;
bv_special old_special = ptile->special;
- struct terrain *type = get_terrain(old_terrain);
- Terrain_type_id new_terrain = type->transform_result;
+ struct terrain *new_terrain = old_terrain->transform_result;
if (old_terrain == new_terrain || new_terrain == T_NONE) {
return -1;
@@ -436,10 +430,10 @@ static int ai_calc_transform(struct city
ptile->terrain = new_terrain;
- if (get_terrain(new_terrain)->mining_result != new_terrain) {
+ if (new_terrain->mining_result != new_terrain) {
tile_clear_special(ptile, S_MINE);
}
- if (get_terrain(new_terrain)->irrigation_result != new_terrain) {
+ if (new_terrain->irrigation_result != new_terrain) {
tile_clear_special(ptile, S_FARMLAND);
tile_clear_special(ptile, S_IRRIGATION);
}
@@ -476,14 +470,14 @@ static int road_bonus(struct tile *ptile
has_road[i] = FALSE;
is_slow[i] = FALSE; /* FIXME: should be TRUE? */
} else {
- struct terrain *ptype = get_terrain(tile1->terrain);
+ struct terrain *pterrain = tile1->terrain;
has_road[i] = tile_has_special(tile1, special);
/* If TRUE, this value indicates that this tile does not need
* a road connector. This is set for terrains which cannot have
* road or where road takes "too long" to build. */
- is_slow[i] = (ptype->road_time == 0 || ptype->road_time > 5);
+ is_slow[i] = (pterrain->road_time == 0 || pterrain->road_time > 5);
if (!has_road[i]) {
unit_list_iterate(tile1->units, punit) {
@@ -1193,7 +1187,7 @@ void initialize_infrastructure_cache(str
city_map_checked_iterate(pcity->tile,
city_x, city_y, ptile) {
#ifndef NDEBUG
- Terrain_type_id old_terrain = ptile->terrain;
+ struct terrain *old_terrain = ptile->terrain;
bv_special old_special = ptile->special;
#endif
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.369
diff -p -u -r1.369 unittools.c
--- server/unittools.c 9 Jul 2005 17:46:09 -0000 1.369
+++ server/unittools.c 12 Jul 2005 15:43:31 -0000
@@ -774,7 +774,8 @@ static void update_unit_activity(struct
if (activity == ACTIVITY_IRRIGATE) {
if (total_activity (ptile, ACTIVITY_IRRIGATE)
>= tile_activity_time(ACTIVITY_IRRIGATE, ptile)) {
- Terrain_type_id old = tile_get_terrain(ptile);
+ struct terrain *old = tile_get_terrain(ptile);
+
tile_apply_activity(ptile, ACTIVITY_IRRIGATE);
solvency = check_terrain_ocean_land_change(ptile, old);
unit_activity_done = TRUE;
@@ -801,7 +802,7 @@ static void update_unit_activity(struct
if (activity == ACTIVITY_MINE) {
if (total_activity (ptile, ACTIVITY_MINE)
>= tile_activity_time(ACTIVITY_MINE, ptile)) {
- Terrain_type_id old = tile_get_terrain(ptile);
+ struct terrain *old = tile_get_terrain(ptile);
tile_apply_activity(ptile, ACTIVITY_MINE);
solvency = check_terrain_ocean_land_change(ptile, old);
@@ -813,7 +814,7 @@ static void update_unit_activity(struct
if (activity == ACTIVITY_TRANSFORM) {
if (total_activity (ptile, ACTIVITY_TRANSFORM)
>= tile_activity_time(ACTIVITY_TRANSFORM, ptile)) {
- Terrain_type_id old = tile_get_terrain(ptile);
+ struct terrain *old = tile_get_terrain(ptile);
tile_apply_activity(ptile, ACTIVITY_TRANSFORM);
solvency = check_terrain_ocean_land_change(ptile, old);
@@ -1205,7 +1206,7 @@ bool enemies_at(struct unit *punit, stru
}
/* Calculate how well we can defend at (x,y) */
- db = 10 + get_terrain(tile_get_terrain(ptile))->defense_bonus / 10;
+ db = 10 + tile_get_terrain(ptile)->defense_bonus / 10;
if (tile_has_special(ptile, S_RIVER))
db += (db * terrain_control.river_defense_bonus) / 100;
d = unit_def_rating_basic_sq(punit) * db;
@@ -2611,7 +2612,7 @@ static void wakeup_neighbor_sentries(str
unit_list_iterate(ptile->units, penemy) {
int range;
enum unit_move_type move_type = unit_type(penemy)->move_type;
- Terrain_type_id terrain = tile_get_terrain(ptile);
+ struct terrain *pterrain = tile_get_terrain(ptile);
if (tile_has_special(ptile, S_FORTRESS)
&& unit_profits_of_watchtower(penemy))
@@ -2624,7 +2625,7 @@ static void wakeup_neighbor_sentries(str
&& range >= real_map_distance(punit->tile, ptile)
&& can_player_see_unit(unit_owner(penemy), punit)
/* on board transport; don't awaken */
- && !(move_type == LAND_MOVING && is_ocean(terrain))) {
+ && !(move_type == LAND_MOVING && is_ocean(pterrain))) {
set_unit_activity(penemy, ACTIVITY_IDLE);
send_unit_info(NULL, penemy);
}
Index: server/generator/mapgen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/mapgen.c,v
retrieving revision 1.28
diff -p -u -r1.28 mapgen.c
--- server/generator/mapgen.c 9 Jul 2005 17:46:09 -0000 1.28
+++ server/generator/mapgen.c 12 Jul 2005 15:43:32 -0000
@@ -235,24 +235,26 @@ static bool terrain_is_too_high(struct t
If the avoid property is given, then any terrain with (any of) that
property will be avoided.
+
+ This function must always return a valid terrain.
****************************************************************************/
-static Terrain_type_id pick_terrain(enum mapgen_terrain_property target,
+static struct terrain *pick_terrain(enum mapgen_terrain_property target,
enum mapgen_terrain_property prefer,
enum mapgen_terrain_property avoid)
{
int sum = 0;
/* Find the total weight. */
- terrain_type_iterate(terrain) {
- if (avoid != MG_LAST && get_terrain(terrain)->property[avoid] > 0) {
+ terrain_type_iterate(pterrain) {
+ if (avoid != MG_LAST && pterrain->property[avoid] > 0) {
continue;
}
- if (prefer != MG_LAST && get_terrain(terrain)->property[prefer] == 0) {
+ if (prefer != MG_LAST && pterrain->property[prefer] == 0) {
continue;
}
if (target != MG_LAST) {
- sum += get_terrain(terrain)->property[target];
+ sum += pterrain->property[target];
} else {
sum++;
}
@@ -262,23 +264,23 @@ static Terrain_type_id pick_terrain(enum
sum = myrand(sum);
/* Finally figure out which one we picked. */
- terrain_type_iterate(terrain) {
+ terrain_type_iterate(pterrain) {
int property;
- if (avoid != MG_LAST && get_terrain(terrain)->property[avoid] > 0) {
+ if (avoid != MG_LAST && pterrain->property[avoid] > 0) {
continue;
}
- if (prefer != MG_LAST && get_terrain(terrain)->property[prefer] == 0) {
+ if (prefer != MG_LAST && pterrain->property[prefer] == 0) {
continue;
}
if (target != MG_LAST) {
- property = get_terrain(terrain)->property[target];
+ property = pterrain->property[target];
} else {
property = 1;
}
if (sum < property) {
- return terrain;
+ return pterrain;
}
sum -= property;
} terrain_type_iterate_end;
@@ -296,20 +298,22 @@ static Terrain_type_id pick_terrain(enum
/**************************************************************************
Picks an ocean terrain to match the given depth (as a percentage).
+
+ FIXME: this should return NULL if there is no available ocean.
**************************************************************************/
-static Terrain_type_id pick_ocean(int depth)
+static struct terrain *pick_ocean(int depth)
{
- Terrain_type_id best_terrain = get_flag_terrain(TER_OCEANIC);
- int best_match
- = abs(depth - get_terrain(best_terrain)->property[MG_OCEAN_DEPTH]);
-
- terrain_type_iterate(t) {
- if (terrain_has_flag(t, TER_OCEANIC)) {
- int match = abs(depth - get_terrain(t)->property[MG_OCEAN_DEPTH]);
+ /* FIXME: get_flag_terrain may return NULL if there is no match. */
+ struct terrain *best_terrain = get_flag_terrain(TER_OCEANIC);
+ int best_match = abs(depth - best_terrain->property[MG_OCEAN_DEPTH]);
+
+ terrain_type_iterate(pterrain) {
+ if (terrain_has_flag(pterrain, TER_OCEANIC)) {
+ int match = abs(depth - pterrain->property[MG_OCEAN_DEPTH]);
if (match < best_match) {
best_match = match;
- best_terrain = t;
+ best_terrain = pterrain;
}
}
} terrain_type_iterate_end;
@@ -336,12 +340,11 @@ static void make_relief(void)
(myrand(10) > 5
|| !terrain_is_too_high(ptile, hmap_mountain_level, hmap(ptile))))
|| terrain_is_too_flat(ptile, hmap_mountain_level, hmap(ptile)))) {
- Terrain_type_id terrain
- = pick_terrain(MG_MOUNTAINOUS,
- MG_LAST,
+ struct terrain *pterrain
+ = pick_terrain(MG_MOUNTAINOUS, MG_LAST,
(tmap_is(ptile, TT_NHOT) ? MG_GREEN : MG_LAST));
- tile_set_terrain(ptile, terrain);
+ tile_set_terrain(ptile, pterrain);
map_set_placed(ptile);
}
} whole_map_iterate_end;
@@ -373,8 +376,9 @@ static bool ok_for_separate_poles(struct
return TRUE;
}
adjc_iterate(ptile, tile1) {
- if (!is_ocean(tile_get_terrain(tile1)) &&
- tile_get_continent(tile1) != 0) {
+ if (tile1->terrain != T_UNKNOWN
+ && !is_ocean(tile_get_terrain(tile1))
+ && tile_get_continent(tile1) != 0) {
return FALSE;
}
} adjc_iterate_end;
@@ -405,7 +409,7 @@ static void make_polar_land(void)
Recursively generate terrains.
**************************************************************************/
static void place_terrain(struct tile *ptile, int diff,
- Terrain_type_id ter, int *to_be_placed,
+ struct terrain *pterrain, int *to_be_placed,
wetness_c wc,
temperature_type tc,
miscellaneous_c mc)
@@ -414,7 +418,7 @@ static void place_terrain(struct tile *p
return;
}
assert(not_placed(ptile));
- tile_set_terrain(ptile, ter);
+ tile_set_terrain(ptile, pterrain);
map_set_placed(ptile);
(*to_be_placed)--;
@@ -427,7 +431,8 @@ static void place_terrain(struct tile *p
&& test_miscellaneous(tile1, mc)
&& Delta < diff
&& myrand(10) > 4) {
- place_terrain(tile1, diff - 1 - Delta, ter, to_be_placed, wc, tc, mc);
+ place_terrain(tile1, diff - 1 - Delta, pterrain,
+ to_be_placed, wc, tc, mc);
}
} cardinal_adjc_iterate_end;
}
@@ -584,7 +589,7 @@ static int river_test_rivergrid(struct t
*********************************************************************/
static int river_test_highlands(struct tile *ptile)
{
- return get_terrain(ptile->terrain)->property[MG_MOUNTAINOUS];
+ return ptile->terrain->property[MG_MOUNTAINOUS];
}
/*********************************************************************
@@ -611,7 +616,7 @@ static int river_test_adjacent_highlands
int sum = 0;
adjc_iterate(ptile, ptile2) {
- sum += get_terrain(ptile2->terrain)->property[MG_MOUNTAINOUS];
+ sum += ptile2->terrain->property[MG_MOUNTAINOUS];
} adjc_iterate_end;
return sum;
@@ -622,7 +627,7 @@ static int river_test_adjacent_highlands
*********************************************************************/
static int river_test_swamp(struct tile *ptile)
{
- return FC_INFINITY - get_terrain(ptile->terrain)->property[MG_WET];
+ return FC_INFINITY - ptile->terrain->property[MG_WET];
}
/*********************************************************************
@@ -633,7 +638,7 @@ static int river_test_adjacent_swamp(str
int sum = 0;
adjc_iterate(ptile, ptile2) {
- sum += get_terrain(ptile2->terrain)->property[MG_WET];
+ sum += ptile2->terrain->property[MG_WET];
} adjc_iterate_end;
return FC_INFINITY - sum;
@@ -792,7 +797,7 @@ static bool make_river(struct tile *ptil
/* We arbitrarily make rivers end at the poles. */
if (count_special_near_tile(ptile, TRUE, TRUE, S_RIVER) > 0
|| count_ocean_near_tile(ptile, TRUE, TRUE) > 0
- || (get_terrain(ptile->terrain)->property[MG_FROZEN] > 0
+ || (ptile->terrain->property[MG_FROZEN] > 0
&& map_colatitude(ptile) < 0.8 * COLD_LEVEL)) {
freelog(LOG_DEBUG,
@@ -946,17 +951,17 @@ static void make_rivers(void)
/* Don't start a river on hills unless it is hard to find
somewhere else to start it. */
- && (get_terrain(ptile->terrain)->property[MG_MOUNTAINOUS] == 0
+ && (ptile->terrain->property[MG_MOUNTAINOUS] == 0
|| iteration_counter >= RIVERS_MAXTRIES / 10 * 6)
/* Don't start a river on arctic unless it is hard to find
somewhere else to start it. */
- && (get_terrain(ptile->terrain)->property[MG_FROZEN] == 0
+ && (ptile->terrain->property[MG_FROZEN] == 0
|| iteration_counter >= RIVERS_MAXTRIES / 10 * 8)
/* Don't start a river on desert unless it is hard to find
somewhere else to start it. */
- && (get_terrain(ptile->terrain)->property[MG_DRY] == 0
+ && (ptile->terrain->property[MG_DRY] == 0
|| iteration_counter >= RIVERS_MAXTRIES / 10 * 9)) {
/* Reset river_map before making a new river. */
@@ -971,12 +976,14 @@ static void make_rivers(void)
if (make_river(ptile)) {
whole_map_iterate(tile1) {
if (TEST_BIT(rmap(tile1), RS_RIVER)) {
- Terrain_type_id t = tile_get_terrain(tile1);
+ struct terrain *pterrain = tile_get_terrain(tile1);
- if (!terrain_has_flag(t, TER_CAN_HAVE_RIVER)) {
+ if (!terrain_has_flag(pterrain, TER_CAN_HAVE_RIVER)) {
/* We have to change the terrain to put a river here. */
- t = get_flag_terrain(TER_CAN_HAVE_RIVER);
- tile_set_terrain(tile1, t);
+ /* FIXME: get_flag_terrain may return NULL
+ * if there is no match. */
+ pterrain = get_flag_terrain(TER_CAN_HAVE_RIVER);
+ tile_set_terrain(tile1, pterrain);
}
tile_set_special(tile1, S_RIVER);
current_riverlength++;
@@ -1046,9 +1053,9 @@ static void make_land(void)
**************************************************************************/
static bool is_tiny_island(struct tile *ptile)
{
- Terrain_type_id t = tile_get_terrain(ptile);
+ struct terrain *pterrain = tile_get_terrain(ptile);
- if (is_ocean(t) || get_terrain(t)->property[MG_FROZEN] > 0) {
+ if (is_ocean(pterrain) || pterrain->property[MG_FROZEN] > 0) {
/* The arctic check is needed for iso-maps: the poles may not have
* any cardinally adjacent land tiles, but that's okay. */
return FALSE;
@@ -1087,24 +1094,23 @@ static void print_mapgen_map(void)
int terrain_count[T_COUNT];
int total = 0;
- terrain_type_iterate(t) {
- terrain_count[t] = 0;
+ terrain_type_iterate(pterrain) {
+ terrain_count[pterrain->index] = 0;
} terrain_type_iterate_end;
whole_map_iterate(ptile) {
- Terrain_type_id t = tile_get_terrain(ptile);
+ struct terrain *pterrain = tile_get_terrain(ptile);
- assert(t >= 0 && t < T_COUNT);
- terrain_count[t]++;
- if (!is_ocean(t)) {
+ terrain_count[pterrain->index]++;
+ if (!is_ocean(pterrain)) {
total++;
}
} whole_map_iterate_end;
- terrain_type_iterate(t) {
+ terrain_type_iterate(pterrain) {
freelog(loglevel, "%20s : %4d %d%% ",
- get_terrain_name(t), terrain_count[t],
- (terrain_count[t] * 100 + 50) / total);
+ get_terrain_name(pterrain), terrain_count[pterrain->index],
+ (terrain_count[pterrain->index] * 100 + 50) / total);
} terrain_type_iterate_end;
}
@@ -1321,27 +1327,26 @@ static bool is_special_close(struct tile
****************************************************************************/
static void add_specials(int prob)
{
- Terrain_type_id ttype;
-
whole_map_iterate(ptile) {
- ttype = tile_get_terrain(ptile);
- if (!is_ocean(ttype)
+ const struct terrain *pterrain = tile_get_terrain(ptile);
+
+ if (!is_ocean(pterrain)
&& !is_special_close(ptile)
&& myrand(1000) < prob) {
- if (terrains[ttype].special[0].name[0] != '\0'
- && (terrains[ttype].special[1].name[0] == '\0'
+ if (pterrain->special[0].name[0] != '\0'
+ && (pterrain->special[1].name[0] == '\0'
|| (myrand(100) < 50))) {
tile_set_special(ptile, S_SPECIAL_1);
- } else if (terrains[ttype].special[1].name[0] != '\0') {
+ } else if (pterrain->special[1].name[0] != '\0') {
tile_set_special(ptile, S_SPECIAL_2);
}
- } else if (is_ocean(ttype) && near_safe_tiles(ptile)
+ } else if (is_ocean(pterrain) && near_safe_tiles(ptile)
&& myrand(1000) < prob && !is_special_close(ptile)) {
- if (terrains[ttype].special[0].name[0] != '\0'
- && (terrains[ttype].special[1].name[0] == '\0'
+ if (pterrain->special[0].name[0] != '\0'
+ && (pterrain->special[1].name[0] == '\0'
|| (myrand(100) < 50))) {
tile_set_special(ptile, S_SPECIAL_1);
- } else if (terrains[ttype].special[1].name[0] != '\0') {
+ } else if (pterrain->special[1].name[0] != '\0') {
tile_set_special(ptile, S_SPECIAL_2);
}
}
@@ -1384,10 +1389,10 @@ static struct tile *get_random_map_posit
static void fill_island(int coast, long int *bucket,
int warm0_weight, int warm1_weight,
int cold0_weight, int cold1_weight,
- Terrain_type_id warm0,
- Terrain_type_id warm1,
- Terrain_type_id cold0,
- Terrain_type_id cold1,
+ struct terrain *warm0,
+ struct terrain *warm1,
+ struct terrain *cold0,
+ struct terrain *cold1,
const struct gen234_state *const pstate)
{
int i, k, capac;
@@ -1494,7 +1499,8 @@ static bool is_near_land(struct tile *pt
{
/* Note this function may sometimes be called on land tiles. */
adjc_iterate(ptile, tile1) {
- if (!is_ocean(tile_get_terrain(tile1))) {
+ if (tile1->terrain != T_UNKNOWN
+ && !is_ocean(tile_get_terrain(tile1))) {
return TRUE;
}
} adjc_iterate_end;
Index: server/generator/startpos.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/startpos.c,v
retrieving revision 1.14
diff -p -u -r1.14 startpos.c
--- server/generator/startpos.c 7 Jun 2005 06:17:15 -0000 1.14
+++ server/generator/startpos.c 12 Jul 2005 15:43:32 -0000
@@ -41,7 +41,7 @@ static int *islands_index;
****************************************************************************/
static int get_tile_value(struct tile *ptile)
{
- Terrain_type_id old_terrain;
+ struct terrain *old_terrain;
bv_special old_special;
int value, irrig_bonus, mine_bonus;
Index: server/generator/utilities.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/utilities.c,v
retrieving revision 1.14
diff -p -u -r1.14 utilities.c
--- server/generator/utilities.c 23 Apr 2005 17:40:29 -0000 1.14
+++ server/generator/utilities.c 12 Jul 2005 15:43:32 -0000
@@ -79,7 +79,7 @@ void map_unset_placed(struct tile *ptile
void set_all_ocean_tiles_placed(void)
{
whole_map_iterate(ptile) {
- if (is_ocean(tile_get_terrain(ptile))) {
+ if (ptile->terrain != T_UNKNOWN && is_ocean(tile_get_terrain(ptile))) {
map_set_placed(ptile);
}
} whole_map_iterate_end;
Index: server/scripting/api.pkg
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/scripting/api.pkg,v
retrieving revision 1.10
diff -p -u -r1.10 api.pkg
--- server/scripting/api.pkg 4 Jul 2005 17:48:38 -0000 1.10
+++ server/scripting/api.pkg 12 Jul 2005 15:43:32 -0000
@@ -59,7 +59,7 @@ struct Tile {
const int nat_x;
const int nat_y;
- int terrain @ terrain_id;
+ Terrain *terrain;
const int index @ id;
};
Index: server/scripting/api_find.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/scripting/api_find.c,v
retrieving revision 1.6
diff -p -u -r1.6 api_find.c
--- server/scripting/api_find.c 9 Jul 2005 17:46:09 -0000 1.6
+++ server/scripting/api_find.c 12 Jul 2005 15:43:32 -0000
@@ -157,7 +157,8 @@ Terrain *api_find_terrain(int terrain_id
**************************************************************************/
Terrain *api_find_terrain_by_name(const char *name_orig)
{
- Terrain_type_id id = get_terrain_by_name(name_orig);
- return api_find_terrain(id);
+ struct terrain *pterrain = get_terrain_by_name(name_orig);
+
+ return pterrain;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Freeciv-Dev] Re: (PR#13442) access terrains by pointer,
Jason Short <=
|
|