Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2003:
[Freeciv-Dev] (PR#6902) gen-terrain for blended terrain types
Home

[Freeciv-Dev] (PR#6902) gen-terrain for blended terrain types

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#6902) gen-terrain for blended terrain types
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 18 Nov 2003 18:14:54 -0800
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=6902 >

Tilespec.c includes some hard-coding of terrain types.  It would be nice 
to move this information into the ruleset, and even nicer if by doing so 
we can clean up the code.

The only complicated usage is where hills, mountains, and forest tiles 
are "blended" with adjacent hills/mountains/forest.

Basically, which forest tile is drawn depends on the 4 adjacent tiles - 
specifically whether they are forest or not.  The relevant code is:

         tileno = INDEX_NSEW(ttype_near[DIR8_NORTH] == T_FOREST,
                          ttype_near[DIR8_SOUTH] == T_FOREST,
                          ttype_near[DIR8_EAST] == T_FOREST,
                          ttype_near[DIR8_WEST] == T_FOREST);
         ADD_SPRITE_SIMPLE(sprites.tx.spec_forest[tileno]);

which is simple enough.  The most obvious answer is to put a 
T_BLEND_FOREST tag into the ruleset from which the client can infer to 
blend this tile type.

Now this first question is, does this data - information used to draw 
the tiles - even need to go in the ruleset at all?  Is it possible for 
the client to figure out which terrain types need blending all on its 
own?  Although it may be, I haven't thought of such a way yet.

Next we have hills/mountains.  Originally (in civ2 and basic freeciv 
tilesets) these were blended just like forests: hills blended with 
hills; mountains blended with mountains.  But you get much better 
results by blending hills and mountains together, as civ3 and some other 
freeciv tilesets do (this behavior is controlled by a tileset option). 
Again the obvious answer is to add T_BLEND_HILLS and T_BLEND_MOUNTAINS 
flags to the ruleset, and check the tileset option to see if hills and 
mountains are blended together.

Of course this solution is short-sighted.  I think a better one is to 
add a new terrain value blend_type (an integer).  For forests we have 
blend_type==1, for mountains and hills blend_type==1 and for all other 
terrain blend_type==0.  If blend_type!=0, the tilespec code will blend 
the terrain.  Different terrains with the same blend type will only be 
blended if the correct tileset option is set.  This allows a lot more 
flexibility for the rulesets, and also cuts down on the amount of code 
needed by eliminating special cases.

The attached patch shows how the drawing code might be changed by this. 
  However, a lot of other code changes will be needed since the new 
value must be added to the rulesets, read in, sent to the client, and 
used by the client in loading the tileset.  If there are no objections 
to this design I will eventually write a full patch.

jason

? genlist_safe_unlink.diff
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.133
diff -u -r1.133 tilespec.c
--- client/tilespec.c   2003/10/15 21:15:46     1.133
+++ client/tilespec.c   2003/11/19 02:09:31
@@ -1525,24 +1525,6 @@
     return NULL;
 }
 
-/**********************************************************************
-  Return TRUE iff the two mountainous terrain types should be blended.
-
-  If is_mountainous set, the tileset will be "mountainous" and consider
-  adjacent hills and mountains interchangable.  If it's unset then
-  hills will only blend with hills and mountains only with mountains.
-***********************************************************************/
-static bool can_blend_hills_and_mountains(enum tile_terrain_type ttype,
-                                 enum tile_terrain_type ttype_adjc)
-{
-  assert(ttype == T_HILLS || ttype == T_MOUNTAINS);
-  if (is_mountainous) {
-    return ttype_adjc == T_HILLS || ttype_adjc == T_MOUNTAINS;
-  } else {
-    return ttype_adjc == ttype;
-  }
-}
-
 /**************************************************************************
   Add any corner road sprites to the sprite array.
 **************************************************************************/
@@ -1877,41 +1859,24 @@
     } else {
       ADD_SPRITE_SIMPLE(get_tile_type(ttype)->sprite[0]);
 
-      switch (ttype) {
-        case T_HILLS:
-        tileno = INDEX_NSEW(can_blend_hills_and_mountains(T_HILLS,
-                                                 ttype_near[DIR8_NORTH]),
-                           can_blend_hills_and_mountains(T_HILLS,
-                                                 ttype_near[DIR8_SOUTH]),
-                           can_blend_hills_and_mountains(T_HILLS,
-                                                 ttype_near[DIR8_EAST]),
-                           can_blend_hills_and_mountains(T_HILLS,
-                                                 ttype_near[DIR8_WEST]));
-        ADD_SPRITE_SIMPLE(sprites.tx.spec_hill[tileno]);
-        break;
- 
-        case T_FOREST:
-        tileno = INDEX_NSEW(ttype_near[DIR8_NORTH] == T_FOREST,
-                         ttype_near[DIR8_SOUTH] == T_FOREST,
-                         ttype_near[DIR8_EAST] == T_FOREST,
-                         ttype_near[DIR8_WEST] == T_FOREST);
-        ADD_SPRITE_SIMPLE(sprites.tx.spec_forest[tileno]);
-        break;
- 
-        case T_MOUNTAINS:
-        tileno = INDEX_NSEW(can_blend_hills_and_mountains(T_MOUNTAINS,
-                                                 ttype_near[DIR8_NORTH]),
-                           can_blend_hills_and_mountains(T_MOUNTAINS,
-                                                 ttype_near[DIR8_SOUTH]),
-                           can_blend_hills_and_mountains(T_MOUNTAINS,
-                                                 ttype_near[DIR8_EAST]),
-                           can_blend_hills_and_mountains(T_MOUNTAINS,
-                                                 ttype_near[DIR8_WEST]));
-        ADD_SPRITE_SIMPLE(sprites.tx.spec_mountain[tileno]);
-        break;
+      if (tile_types[ttype].blend_type != 0) {
+       bool n, s, e, w;
+       int blend_type = tile_types[ttype].blend_type;
+
+       if (can_blend_multiple) {
+         n = (tile_types[ttype_near[DIR8_NORTH]].blend_type == blend_type);
+         s = (tile_types[ttype_near[DIR8_SOUTH]].blend_type == blend_type);
+         e = (tile_types[ttype_near[DIR8_EAST]].blend_type == blend_type);
+         w = (tile_types[ttype_near[DIR8_WEST]].blend_type == blend_type);
+       } else {
+         n = (ttype_near[DIR8_NORTH] == ttype);
+         s = (ttype_near[DIR8_SOUTH] == ttype);
+         e = (ttype_near[DIR8_EAST] == ttype);
+         w = (ttype_near[DIR8_WEST] == ttype);
+       }
 
-       default:
-       break;
+       tileno = INDEX_NSEW(n, s, e, w);
+       ADD_SPRITE_SIMPLE(sprites.tx.blended[ttype][tileno]);
       }
 
       sprs += fill_irrigation_sprite_array(sprs, tspecial, tspecial_near,

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#6902) gen-terrain for blended terrain types, Jason Short <=