<URL: http://bugs.freeciv.org/Ticket/Display.html?id=39409 >

Here is an improved and more tested patch.

This still uses the three categories for edges. It adds one color for
inactive, unknown edges that are gray. Active edges use the
unreachable_goal color (just reusing to simplify).

No lists, the lists are only needed if paint order is important, but
it is not except for where the edges cross, but that is normally not
noticeable so we don't have to worry about this.

So this patch is now simply:
enum reqtree_edge_type to give names to the edge types
get_edge_type is an internal function to get the type of an edge
edge_color is a function (just like node_color) that returns the color
name for an edge using a mapping from the result of get_edge_type
draw_reqtree is only slightly updated to use the correct colors.
LINE_GOTO is used for thick lines, the colored lines don't do much
difference if the lines are thinner.

Applies to trunk r13013

Index: client/reqtree.c
===================================================================
--- client/reqtree.c	(revision 13013)
+++ client/reqtree.c	(arbetskopia)
@@ -102,6 +102,15 @@
 };
 
 
+/****************************************************************************
+  Edge types for coloring the edges by type in the tree
+****************************************************************************/
+enum reqtree_edge_type {
+  REQTREE_EDGE = 0,     /* Normal, "unvisited" */
+  REQTREE_KNOWN_EDGE,   /* Both nodes known, "visited" */
+  REQTREE_ACTIVE_EDGE   /* Dest node is part of goal "future visited" */
+};
+
 /*************************************************************************
   Add requirement edge to node and provide edge to req
 *************************************************************************/
@@ -873,7 +882,85 @@
 
 }
 
+
 /****************************************************************************
+  Return the type for an edge between two nodes
+  if node is a dummy, dest_node can be NULL
+****************************************************************************/
+static enum reqtree_edge_type get_edge_type(struct tree_node *node, 
+                                            struct tree_node *dest_node)
+{
+  if (dest_node == NULL) {
+    /* assume node is a dummy */
+    dest_node = node;
+  }
+   
+  /* find the required tech */
+  while (node->is_dummy) {
+    assert(node->nrequire == 1);
+    node = node->require[0];
+  }
+  
+  /* find destination advance by recursing in dest_node->provide[]
+   * watch out: recursion */
+  if (dest_node->is_dummy) {
+    assert(dest_node->nprovide > 0);
+    enum reqtree_edge_type sum_type = REQTREE_EDGE;
+    int i;
+    for (i = 0; i < dest_node->nprovide; ++i) {
+      enum reqtree_edge_type type = get_edge_type(node, dest_node->provide[i]);
+      if (type == REQTREE_ACTIVE_EDGE) {
+        sum_type = type;
+        break;
+      }
+      if (type == REQTREE_KNOWN_EDGE) {
+        sum_type = type;
+      }      
+    }
+    return sum_type;
+  }
+
+  struct player_research* research = get_player_research(game.player_ptr);
+
+  if (!game.player_ptr || !research) {
+    return REQTREE_KNOWN_EDGE; /* Global observer case */
+  }
+  
+  if (get_invention(game.player_ptr, dest_node->tech) == TECH_KNOWN) {
+    if (get_invention(game.player_ptr, node->tech) == TECH_KNOWN) {
+      return REQTREE_KNOWN_EDGE;
+    } else {
+      return REQTREE_EDGE; /* required advance not known */
+    }
+  }
+
+  if (is_tech_a_req_for_goal(game.player_ptr, dest_node->tech,
+		       research->tech_goal)
+                       || research->researching == dest_node->tech
+                       || research->tech_goal == dest_node->tech) {
+    return REQTREE_ACTIVE_EDGE;
+  }
+  
+  return REQTREE_EDGE;
+}
+
+/****************************************************************************
+  Return a stroke color for an edge between two nodes
+  if node is a dummy, dest_node can be NULL
+****************************************************************************/
+static enum color_std edge_color(struct tree_node *node, 
+                                 struct tree_node *dest_node)
+{
+  enum reqtree_edge_type type = get_edge_type(node, dest_node);
+  if (type == REQTREE_ACTIVE_EDGE)
+    return COLOR_REQTREE_UNREACHABLE_GOAL;
+  else if (type == REQTREE_KNOWN_EDGE)
+    return COLOR_REQTREE_BACKGROUND;
+  else
+    return COLOR_REQTREE_EDGE;
+}
+
+/****************************************************************************
   Draw the reqtree diagram!
 
   This draws the given portion of the reqtree diagram (given by
@@ -901,9 +988,9 @@
       if (node->is_dummy) {
         /* Use the same layout as lines for dummy nodes */
         canvas_put_line(pcanvas,
-			get_color(tileset, COLOR_REQTREE_BACKGROUND),
-			LINE_NORMAL,
-			startx, starty, width, 0);
+		        get_color(tileset, edge_color(node, NULL)),
+		        LINE_GOTO,
+		        startx, starty, width, 0);
       } else {
 	const char *text = advance_name_for_player(game.player_ptr, node->tech);
 	int text_w, text_h;
@@ -993,11 +1080,11 @@
 
 	endx = dest_node->node_x;
 	endy = dest_node->node_y + dest_node->node_height / 2;
-
+	
 	canvas_put_line(pcanvas,
-			get_color(tileset, COLOR_REQTREE_BACKGROUND),
-			LINE_NORMAL,
-			startx, starty, endx - startx, endy - starty);
+		        get_color(tileset, edge_color(node, dest_node)),
+		        LINE_GOTO,
+		        startx, starty, endx - startx, endy - starty);
       }
     }
   }
Index: client/colors_common.c
===================================================================
--- client/colors_common.c	(revision 13013)
+++ client/colors_common.c	(arbetskopia)
@@ -82,6 +82,7 @@
   "reqtree_unreachable",
   "reqtree_background",
   "reqtree_text",
+  "reqtree_edge",
 
   /* Player dialog */
   "playerdlg_background"
Index: client/colors_common.h
===================================================================
--- client/colors_common.h	(revision 13013)
+++ client/colors_common.h	(arbetskopia)
@@ -57,6 +57,7 @@
   COLOR_REQTREE_UNREACHABLE, /* red */
   COLOR_REQTREE_BACKGROUND, /* black */
   COLOR_REQTREE_TEXT, /* black */
+  COLOR_REQTREE_EDGE, /* gray */
   
   /* Player dialog */
   COLOR_PLAYER_COLOR_BACKGROUND, /* black */
Index: data/misc/colors.tilespec
===================================================================
--- data/misc/colors.tilespec	(revision 13007)
+++ data/misc/colors.tilespec	(arbetskopia)
@@ -114,6 +114,10 @@
 reqtree_text = {"r", "g", "b"
     0,   0,   0
 }
+
+reqtree_edge = {"r", "g", "b"
+    127,   127,   127
+}
   
 ; Player dialog
 playerdlg_background = {"r", "g", "b"
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to