Complete.Org: Mailing Lists: Archives: freeciv-dev: October 2004:
[Freeciv-Dev] (PR#9821) enum values saved in savegame
Home

[Freeciv-Dev] (PR#9821) enum values saved in savegame

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#9821) enum values saved in savegame
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 7 Oct 2004 17:54:14 -0700
Reply-to: rt@xxxxxxxxxxx

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

Here is a patch.  It's a bit long but should be robust.

jason

Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.219.2.1
diff -u -r1.219.2.1 map.h
--- common/map.h        7 Oct 2004 19:15:21 -0000       1.219.2.1
+++ common/map.h        8 Oct 2004 00:53:44 -0000
@@ -158,6 +158,8 @@
   DIR8_SOUTH = 6,
   DIR8_SOUTHEAST = 7
 };
+#define DIR8_LAST 8
+#define DIR8_COUNT DIR8_LAST
 
 struct civ_map {
   int topology_id;
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.197
diff -u -r1.197 savegame.c
--- server/savegame.c   4 Oct 2004 04:37:33 -0000       1.197
+++ server/savegame.c   8 Oct 2004 00:53:46 -0000
@@ -16,6 +16,7 @@
 #endif
 
 #include <assert.h>
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -252,6 +253,173 @@
   }
 }
 
+/****************************************************************************
+  Returns an order for a character identifier.  See also order2char.
+****************************************************************************/
+static enum unit_orders char2order(char order)
+{
+  switch (order) {
+  case 'm':
+  case 'M':
+    return ORDER_MOVE;
+  case 'w':
+  case 'W':
+    return ORDER_FINISH_TURN;
+  case 'a':
+  case 'A':
+    return ORDER_ACTIVITY;
+  }
+
+  /* This can happen if the savegame is invalid. */
+  return ORDER_LAST;
+}
+
+/****************************************************************************
+  Returns a character identifier for an order.  See also char2order.
+****************************************************************************/
+static char order2char(enum unit_orders order)
+{
+  switch (order) {
+  case ORDER_MOVE:
+    return 'm';
+  case ORDER_FINISH_TURN:
+    return 'w';
+  case ORDER_ACTIVITY:
+    return 'a';
+  case ORDER_LAST:
+    break;
+  }
+
+  assert(0);
+  return '?';
+}
+
+/****************************************************************************
+  Returns a direction for a character identifier.  See also dir2char.
+****************************************************************************/
+static enum direction8 char2dir(char dir)
+{
+  /* Numberpad values for the directions. */
+  switch (dir) {
+  case '1':
+    return DIR8_SOUTHWEST;
+  case '2':
+    return DIR8_SOUTH;
+  case '3':
+    return DIR8_SOUTHEAST;
+  case '4':
+    return DIR8_WEST;
+  case '6':
+    return DIR8_EAST;
+  case '7':
+    return DIR8_NORTHWEST;
+  case '8':
+    return DIR8_NORTH;
+  case '9':
+    return DIR8_NORTHEAST;
+  }
+
+  /* This can happen if the savegame is invalid. */
+  return DIR8_LAST;
+}
+
+/****************************************************************************
+  Returns a character identifier for a direction.  See also char2dir.
+****************************************************************************/
+static char dir2char(enum direction8 dir)
+{
+  /* Numberpad values for the directions. */
+  switch (dir) {
+  case DIR8_NORTH:
+    return '8';
+  case DIR8_SOUTH:
+    return '2';
+  case DIR8_EAST:
+    return '6';
+  case DIR8_WEST:
+    return '4';
+  case DIR8_NORTHEAST:
+    return '9';
+  case DIR8_NORTHWEST:
+    return '7';
+  case DIR8_SOUTHEAST:
+    return '3';
+  case DIR8_SOUTHWEST:
+    return '1';
+  }
+
+  assert(0);
+  return '?';
+}
+
+/****************************************************************************
+  Returns a character identifier for an activity.  See also char2activity.
+****************************************************************************/
+static char activity2char(enum unit_activity activity)
+{
+  switch (activity) {
+  case ACTIVITY_IDLE:
+    return 'w';
+  case ACTIVITY_POLLUTION:
+    return 'p';
+  case ACTIVITY_ROAD:
+    return 'r';
+  case ACTIVITY_MINE:
+    return 'm';
+  case ACTIVITY_IRRIGATE:
+    return 'i';
+  case ACTIVITY_FORTIFIED:
+    return 'f';
+  case ACTIVITY_FORTRESS:
+    return 't';
+  case ACTIVITY_SENTRY:
+    return 's';
+  case ACTIVITY_RAILROAD:
+    return 'l';
+  case ACTIVITY_PILLAGE:
+    return 'e';
+  case ACTIVITY_GOTO:
+    return 'g';
+  case ACTIVITY_EXPLORE:
+    return 'x';
+  case ACTIVITY_TRANSFORM:
+    return 'o';
+  case ACTIVITY_AIRBASE:
+    return 'a';
+  case ACTIVITY_FORTIFYING:
+    return 'y';
+  case ACTIVITY_FALLOUT:
+    return 'u';
+  case ACTIVITY_UNKNOWN:
+  case ACTIVITY_PATROL_UNUSED:
+    return '?';
+  case ACTIVITY_LAST:
+    break;
+  }
+
+  assert(0);
+  return '?';
+}
+
+/****************************************************************************
+  Returns an activity for a character identifier.  See also activity2char.
+****************************************************************************/
+static enum unit_activity char2activity(char activity)
+{
+  enum unit_activity a;
+
+  for (a = 0; a < ACTIVITY_LAST; a++) {
+    char achar = activity2char(a);
+
+    if (activity == achar || activity == toupper(achar)) {
+      return a;
+    }
+  }
+
+  /* This can happen if the savegame is invalid. */
+  return ACTIVITY_LAST;
+}
+
 /***************************************************************
 Quote the memory block denoted by data and length so it consists only
 of " a-f0-9:". The returned string has to be freed by the caller using
@@ -1345,15 +1513,27 @@
                        "player%d.u%d.activity_list", plrno, i);
        punit->has_orders = TRUE;
        for (j = 0; j < len; j++) {
+         struct unit_order *order = &punit->orders.list[j];
+
          if (orders_buf[j] == '\0' || dir_buf[j] == '\0'
              || act_buf[j] == '\0') {
            freelog(LOG_ERROR, _("Savegame error: invalid unit orders."));
            free_unit_orders(punit);
            break;
          }
-         punit->orders.list[j].order = orders_buf[j] - 'a';
-         punit->orders.list[j].dir = dir_buf[j] - 'a';
-         punit->orders.list[j].activity = act_buf[j] - 'a';
+         order->order = char2order(orders_buf[j]);
+         order->dir = char2dir(dir_buf[j]);
+         order->activity = char2activity(act_buf[j]);
+         if (order->order == ORDER_LAST
+             || (order->order == ORDER_MOVE && order->dir == DIR8_LAST)
+             || (order->order == ORDER_ACTIVITY
+                 && order->activity == ACTIVITY_LAST)) {
+           /* An invalid order.  Just drop the orders for this unit. */
+           free(punit->orders.list);
+           punit->orders.list = NULL;
+           punit->has_orders = FALSE;
+           break;
+         }
        }
       } else {
        punit->has_orders = FALSE;
@@ -2461,9 +2641,20 @@
                          "player%d.u%d.orders_vigilant", plrno, i);
 
       for (j = 0; j < len; j++) {
-       orders_buf[j] = 'a' + punit->orders.list[j].order;
-       dir_buf[j] = 'a' + punit->orders.list[j].dir;
-       act_buf[j] = 'a' + punit->orders.list[j].activity;
+       orders_buf[j] = order2char(punit->orders.list[j].order);
+       dir_buf[j] = '?';
+       act_buf[j] = '?';
+       switch (punit->orders.list[j].order) {
+       case ORDER_MOVE:
+         dir_buf[j] = dir2char(punit->orders.list[j].dir);
+         break;
+       case ORDER_ACTIVITY:
+         act_buf[j] = activity2char(punit->orders.list[j].activity);
+         break;
+       case ORDER_FINISH_TURN:
+       case ORDER_LAST:
+         break;
+       }
       }
       orders_buf[len] = dir_buf[len] = act_buf[len] = '\0';
 

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#9821) enum values saved in savegame, Jason Short <=