Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2003:
[Freeciv-Dev] Re: (PR#3730) New Irrigation/Farmland System
Home

[Freeciv-Dev] Re: (PR#3730) New Irrigation/Farmland System

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: bursig@xxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#3730) New Irrigation/Farmland System
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 14 Mar 2003 17:56:55 -0800
Reply-to: rt@xxxxxxxxxxxxxx

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,

[Prev in Thread] Current Thread [Next in Thread]