[Freeciv-Dev] Re: (PR#3730) New Irrigation/Farmland System
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Rafa³ Bursig wrote:
> Hi
> This is my old code that I forget send to RT. It add support
> for Civ3 irrigation/farmland multi tile system and is compatible with
> current system.
Nice.
I've made some changes:
- Non-iso view gets support.
- Cleaner loading code using SET_SPRITE_ALT; this also avoids dangling
pointers.
- An additional cleanup: introduce fill_irrigation_sprite_array.
- Move the INDEX_NSEW call behind a wrapper function so it's not duplicated.
- Use contains_special instead of manually doing the bit arithmetic
(note your use of "> 0" here was unsafe, the correct check should be "!=
0").
- We don't have to bother checking for S_FARMLAND when looking at nearby
tiles since it implies S_IRRIGATION (I added an assertion to verify
this, lest someone inadvertently change it).
I also made two *actual* changes in the creation of
fill_irrigation_sprite_array:
- Previously irrigation would be drawn underneath a city in non-iso view
but not in iso view. I see no reason why these two situations should
differ, and in any case having irrigation drawn under the city looks
ugly. So now both cases do _not_draw the irrigation if there is a city
present.
- When checking for the city, also check if draw_cities is specified.
If it's not, then we should draw the irrigation anyway! This is a
rather pervasive bug (it also applies to units).
I haven't been able to test this code with a supporting tileset. Rafal,
can you do this?
jason
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.111
diff -u -r1.111 tilespec.c
--- client/tilespec.c 2003/03/05 08:56:07 1.111
+++ client/tilespec.c 2003/03/15 01:52:44
@@ -832,8 +832,6 @@
SET_SPRITE(user.attention, "user.attention");
SET_SPRITE(tx.fallout, "tx.fallout");
- SET_SPRITE(tx.farmland, "tx.farmland");
- SET_SPRITE(tx.irrigation, "tx.irrigation");
SET_SPRITE(tx.mine, "tx.mine");
SET_SPRITE_ALT(tx.oil_mine, "tx.oil_mine", "tx.mine");
SET_SPRITE(tx.pollution, "tx.pollution");
@@ -848,6 +846,18 @@
SET_SPRITE(tx.spec_river[i], buffer);
}
+ /* We use direction-specific irrigation and farmland graphics, if they
+ * are available. If not, we just fall back to the basic irrigation
+ * graphics. */
+ for (i = 0; i < NUM_DIRECTION_NSEW; i++) {
+ my_snprintf(buffer, sizeof(buffer), "tx.s_irrigation_%s", nsew_str(i));
+ SET_SPRITE_ALT(tx.irrigation[i], buffer, "tx.irrigation");
+ }
+ for (i = 0; i < NUM_DIRECTION_NSEW; i++) {
+ my_snprintf(buffer, sizeof(buffer), "tx.s_farmland_%s", nsew_str(i));
+ SET_SPRITE_ALT(tx.farmland[i], buffer, "tx.farmland");
+ }
+
if (is_isometric) {
for(i=0; i<NUM_DIRECTION_NSEW; i++) {
my_snprintf(buffer, sizeof(buffer), "tx.s_forest_%s", nsew_str(i));
@@ -1698,6 +1708,55 @@
return sprs - saved_sprs;
}
+/**************************************************************************
+ Return the index of the sprite to be used for irrigation or farmland in
+ this tile.
+
+ We assume that the current tile has farmland or irrigation. We then
+ choose a sprite (index) based upon which cardinally adjacent tiles have
+ either farmland or irrigation (the two are considered interchangable for
+ this).
+**************************************************************************/
+static int get_irrigation_index(enum tile_special_type *tspecial_near)
+{
+ /* A tile with S_FARMLAND will also have S_IRRIGATION set. */
+ bool n = contains_special(tspecial_near[DIR8_NORTH], S_IRRIGATION);
+ bool s = contains_special(tspecial_near[DIR8_SOUTH], S_IRRIGATION);
+ bool e = contains_special(tspecial_near[DIR8_EAST], S_IRRIGATION);
+ bool w = contains_special(tspecial_near[DIR8_WEST], S_IRRIGATION);
+
+ return INDEX_NSEW(n, s, e, w);
+}
+
+/**************************************************************************
+ Fill in the farmland/irrigation sprite for the tile.
+**************************************************************************/
+static int fill_irrigation_sprite_array(struct Sprite **sprs,
+ enum tile_special_type tspecial,
+ enum tile_special_type *tspecial_near,
+ struct city *pcity)
+{
+ struct Sprite **saved_sprs = sprs;
+
+ /* Tiles with S_FARMLAND also have S_IRRIGATION set. */
+ assert(!contains_special(tspecial, S_FARMLAND)
+ || contains_special(tspecial, S_IRRIGATION));
+
+ /* We don't draw the irrigation if there's a city (it just gets overdrawn
+ * anyway, and ends up looking bad). */
+ if (draw_irrigation
+ && contains_special(tspecial, S_IRRIGATION)
+ && !(pcity && draw_cities)) {
+ if (contains_special(tspecial, S_FARMLAND)) {
+ *sprs++ = sprites.tx.farmland[get_irrigation_index(tspecial_near)];
+ } else {
+ *sprs++ = sprites.tx.irrigation[get_irrigation_index(tspecial_near)];
+ }
+ }
+
+ return sprs - saved_sprs;
+}
+
/**********************************************************************
Fill in the sprite array for the tile at position (abs_x0,abs_y0).
Does not fill in the city or unit; that have to be done seperatly in
@@ -1778,14 +1837,10 @@
default:
break;
- }
-
- if (contains_special(tspecial, S_IRRIGATION) && !pcity &&
draw_irrigation) {
- if (contains_special(tspecial, S_FARMLAND))
- *sprs++ = sprites.tx.farmland;
- else
- *sprs++ = sprites.tx.irrigation;
}
+
+ sprs += fill_irrigation_sprite_array(sprs, tspecial, tspecial_near,
+ pcity);
if (contains_special(tspecial, S_RIVER)) {
tileno = INDEX_NSEW(contains_special(tspecial_near[DIR8_NORTH], S_RIVER)
@@ -1802,12 +1857,10 @@
} else {
*solid_bg = 1;
- if (contains_special(tspecial, S_IRRIGATION) && !pcity && draw_irrigation)
{
- if (contains_special(tspecial, S_FARMLAND))
- *sprs++ = sprites.tx.farmland;
- else
- *sprs++ = sprites.tx.irrigation;
- }
+ /* This call is duplicated because it is normally
+ * drawn underneath rivers. */
+ sprs += fill_irrigation_sprite_array(sprs, tspecial, tspecial_near,
+ pcity);
}
if (is_ocean(ttype)) {
@@ -2019,12 +2072,8 @@
|| is_ocean(ttype_near[DIR8_WEST]));
*sprs++=sprites.tx.spec_river[tileno];
}
-
- if(contains_special(tspecial, S_IRRIGATION) && draw_irrigation) {
- if(contains_special(tspecial, S_FARMLAND)) *sprs++=sprites.tx.farmland;
- else *sprs++=sprites.tx.irrigation;
- }
+ sprs += fill_irrigation_sprite_array(sprs, tspecial, tspecial_near, pcity);
sprs += fill_road_rail_sprite_array(sprs, tspecial, tspecial_near, pcity);
if(draw_specials) {
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.38
diff -u -r1.38 tilespec.h
--- client/tilespec.h 2003/02/02 00:15:52 1.38
+++ client/tilespec.h 2003/03/15 01:52:44
@@ -178,8 +178,8 @@
} user;
struct {
struct Sprite
- *farmland,
- *irrigation,
+ *farmland[NUM_DIRECTION_NSEW],
+ *irrigation[NUM_DIRECTION_NSEW],
*mine,
*oil_mine,
*pollution,
|
|