Author: jtn
Date: Tue Jun 17 00:00:06 2014
New Revision: 25166

URL: http://svn.gna.org/viewcvs/freeciv?rev=25166&view=rev
Log:
Fix minor bugs in display of fractional movement points resulting from
generalisation of move_fragments, and reduce fractional MP to lowest terms.
Use move_points_text() in road helptext.

See gna bug #22194.

Modified:
    branches/S2_5/client/helpdata.c
    branches/S2_5/client/packhand.c
    branches/S2_5/common/movement.c
    branches/S2_5/common/movement.h
    branches/S2_5/server/ruleset.c

Modified: branches/S2_5/client/helpdata.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/helpdata.c?rev=25166&r1=25165&r2=25166&view=diff
==============================================================================
--- branches/S2_5/client/helpdata.c     (original)
+++ branches/S2_5/client/helpdata.c     Tue Jun 17 00:00:06 2014
@@ -3097,8 +3097,11 @@
     CATLSTR(buf, bufsz, _("* Allows infinite movement.\n"));
   } else {
     cat_snprintf(buf, bufsz,
-                 _("* Movement cost along this road is %d/%d movement 
points.\n"),
-                 proad->move_cost, SINGLE_MOVE);
+                 /* TRANS: "MP" = movement points. Second %s may have a
+                  * fractional part. */
+                 _("* Movement cost along %s is %s MP.\n"),
+                 road_name_translation(proad),
+                 move_points_text(proad->move_cost, NULL, NULL, FALSE));
   }
 
   if (!proad->buildable) {

Modified: branches/S2_5/client/packhand.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/packhand.c?rev=25166&r1=25165&r2=25166&view=diff
==============================================================================
--- branches/S2_5/client/packhand.c     (original)
+++ branches/S2_5/client/packhand.c     Tue Jun 17 00:00:06 2014
@@ -34,6 +34,7 @@
 #include "government.h"
 #include "idex.h"
 #include "map.h"
+#include "movement.h"
 #include "name_translation.h"
 #include "nation.h"
 #include "packets.h"
@@ -3366,6 +3367,8 @@
   /* Since terrain_control is the same as packet_ruleset_terrain_control
    * we can just copy the data directly. */
   terrain_control = *p;
+  /* terrain_control.move_fragments likely changed */
+  init_move_fragments();
 }
 
 /****************************************************************************

Modified: branches/S2_5/common/movement.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/movement.c?rev=25166&r1=25165&r2=25166&view=diff
==============================================================================
--- branches/S2_5/common/movement.c     (original)
+++ branches/S2_5/common/movement.c     Tue Jun 17 00:00:06 2014
@@ -618,9 +618,23 @@
   return availability;
 }
 
-/****************************************************************************
-  Render movement points as text, including fractional movement points,
-  scaled by SINGLE_MOVE. Returns a pointer to a static buffer.
+static int move_points_denomlen = 0;
+
+/****************************************************************************
+  Call whenever terrain_control.move_fragments / SINGLE_MOVE changes.
+****************************************************************************/
+void init_move_fragments(void)
+{
+  char denomstr[10];
+  /* String length of maximum denominator for fractional representation of
+   * movement points, for padding of text representation */
+  fc_snprintf(denomstr, sizeof(denomstr), "%d", SINGLE_MOVE);
+  move_points_denomlen = strlen(denomstr);
+}
+
+/****************************************************************************
+  Render positive movement points as text, including fractional movement
+  points, scaled by SINGLE_MOVE. Returns a pointer to a static buffer.
   'prefix' is a string put in front of all numeric output.
   'none' is the string to display in place of the integer part if no
   movement points (or NULL to just say 0).
@@ -632,45 +646,51 @@
                              bool align)
 {
   static struct astring str = ASTRING_INIT;
-  static int denomlen = 0;
   int pad1, pad2;
 
-  if (denomlen == 0) {
-    /* String length of denominator for fractional representation of
-     * movement points, for padding */
-    char denomstr[10];
-    fc_snprintf(denomstr, sizeof(denomstr), "%d", SINGLE_MOVE);
-    denomlen = strlen(denomstr);
-  }
-  if (align) {
-    pad1 = denomlen;     /* numerator or denominator */
-    pad2 = denomlen*2+2; /* everything right of integer part */
+  if (align && SINGLE_MOVE > 1) {
+    pad1 = move_points_denomlen;      /* numerator or denominator */
+    pad2 = move_points_denomlen*2+2;  /* everything right of integer part */
   } else {
+    /* If no fractional part, no need for alignment even if requested */
     pad1 = pad2 = 0;
   }
   if (!prefix) {
     prefix = "";
   }
   astr_clear(&str);
-  if ((mp == 0 || SINGLE_MOVE == 0) && none) {
-    /* No movement points, special representation */
-    astr_add(&str, "%s%*s", none, pad2, "");
-  } else if (SINGLE_MOVE == 0) {
-    /* Do not divide by zero. Important for client before ruleset
-     * received. Just add */
-    astr_add(&str, "0/0");
+  if ((mp == 0 && none) || SINGLE_MOVE == 0) {
+    /* No movement points, and we have a special representation to use */
+    /* (Also used when SINGLE_MOVE==0, to avoid dividing by zero, which is
+     * important for client before ruleset has been received. Doesn't much
+     * matter what we print in this case.) */
+    astr_add(&str, "%s%*s", none ? none : "", pad2, "");
   } else if ((mp % SINGLE_MOVE) == 0) {
-    /* Integer move bonus */
+    /* Integer move points */
     astr_add(&str, "%s%d%*s", prefix, mp / SINGLE_MOVE, pad2, "");
-  } else if (mp < SINGLE_MOVE) {
-    /* Fractional move bonus */
-    astr_add(&str, "%s%*d/%*d", prefix,
-             pad1, mp % SINGLE_MOVE, pad1, SINGLE_MOVE);
   } else {
-    /* Integer + fractional move bonus */
-    astr_add(&str,
-             "%s%d %*d/%*d", prefix, mp / SINGLE_MOVE,
-             pad1, mp % SINGLE_MOVE, pad1, SINGLE_MOVE);
+    /* Fractional part; reduce to lowest terms */
+    int gcd = mp;
+    fc_assert(SINGLE_MOVE > 1);
+    {
+      /* Calculate greatest common divisor with Euclid's algorithm */
+      int b = SINGLE_MOVE;
+      while (b != 0) {
+        int t = b;
+        b = gcd % b;
+        gcd = t;
+      }
+    }
+    if (mp < SINGLE_MOVE) {
+      /* Fractional move points */
+      astr_add(&str, "%s%*d/%*d", prefix,
+               pad1, (mp % SINGLE_MOVE) / gcd, pad1, SINGLE_MOVE / gcd);
+    } else {
+      /* Integer + fractional move points */
+      astr_add(&str,
+               "%s%d %*d/%*d", prefix, mp / SINGLE_MOVE,
+               pad1, (mp % SINGLE_MOVE) / gcd, pad1, SINGLE_MOVE / gcd);
+    }
   }
   return astr_str(&str);
 }

Modified: branches/S2_5/common/movement.h
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/movement.h?rev=25166&r1=25165&r2=25166&view=diff
==============================================================================
--- branches/S2_5/common/movement.h     (original)
+++ branches/S2_5/common/movement.h     Tue Jun 17 00:00:06 2014
@@ -97,6 +97,7 @@
                                     const struct unit_class *pclass);
 struct unit *transport_from_tile(struct unit *punit, struct tile *ptile);
 
+void init_move_fragments(void);
 const char *move_points_text(int mp, const char *prefix, const char *none,
                              bool align);
 

Modified: branches/S2_5/server/ruleset.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/server/ruleset.c?rev=25166&r1=25165&r2=25166&view=diff
==============================================================================
--- branches/S2_5/server/ruleset.c      (original)
+++ branches/S2_5/server/ruleset.c      Tue Jun 17 00:00:06 2014
@@ -2597,7 +2597,8 @@
   terrain_control.move_fragments
     = secfile_lookup_int_default(file, 3,
                                  "parameters.move_fragments");
- terrain_control.igter_cost
+  init_move_fragments();
+  terrain_control.igter_cost
     = secfile_lookup_int_default(file, 1,
                                  "parameters.igter_cost");
   map.server.ocean_resources


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to