[Freeciv-Dev] (PR#9821) enum values saved in savegame
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<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 <=
|
|