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

Attached patch implements unit properties 'fuel', 'moved'
'done_moving', 'hp' and 'veteran' for the property editor.


-----------------------------------------------------------------------
洗濯しなければ、あの委員会は来て服を押収するよ。
diff --git a/client/gui-gtk-2.0/editprop.c b/client/gui-gtk-2.0/editprop.c
index 94d5670..b7a4202 100644
--- a/client/gui-gtk-2.0/editprop.c
+++ b/client/gui-gtk-2.0/editprop.c
@@ -174,6 +174,7 @@ static bool objtype_is_conserved(int objtype);
 enum value_types {
   VALTYPE_NONE = 0,
   VALTYPE_INT,
+  VALTYPE_BOOL,
   VALTYPE_STRING,
   VALTYPE_PIXBUF,
   VALTYPE_BUILT_ARRAY,        /* struct built_status[B_LAST] */
@@ -196,6 +197,7 @@ static const char *valtype_get_name(int valtype);
 union propval_data {
   gpointer v_pointer;
   int v_int;
+  bool v_bool;
   char *v_string;
   const char *v_const_string;
   GdkPixbuf *v_pixbuf;
@@ -281,6 +283,11 @@ enum object_property_ids {
   OPID_UNIT_ID,
   OPID_UNIT_XY,
   OPID_UNIT_MOVES_LEFT,
+  OPID_UNIT_FUEL,
+  OPID_UNIT_MOVED,
+  OPID_UNIT_DONE_MOVING,
+  OPID_UNIT_HP,
+  OPID_UNIT_VETERAN,
 
   OPID_CITY_IMAGE,
   OPID_CITY_NAME,
@@ -359,6 +366,8 @@ static void objprop_widget_entry_activated(GtkEntry *entry,
                                            gpointer userdata);
 static void objprop_widget_spin_button_changed(GtkSpinButton *spin,
                                                gpointer userdata);
+static void objprop_widget_toggle_button_changed(GtkToggleButton *button,
+                                                 gpointer userdata);
 
 
 /****************************************************************************
@@ -740,6 +749,9 @@ static const char *valtype_get_name(int valtype)
   case VALTYPE_INT:
     return "int";
     break;
+  case VALTYPE_BOOL:
+    return "bool";
+    break;
   case VALTYPE_PIXBUF:
     return "pixbuf";
     break;
@@ -1370,6 +1382,21 @@ static struct propval *objbind_get_value_from_object(struct objbind *ob,
     case OPID_UNIT_MOVES_LEFT:
       pv->data.v_int = punit->moves_left;
       break;
+    case OPID_UNIT_FUEL:
+      pv->data.v_int = punit->fuel;
+      break;
+    case OPID_UNIT_MOVED:
+      pv->data.v_bool = punit->moved;
+      break;
+    case OPID_UNIT_DONE_MOVING:
+      pv->data.v_bool = punit->done_moving;
+      break;
+    case OPID_UNIT_HP:
+      pv->data.v_int = punit->hp;
+      break;
+    case OPID_UNIT_VETERAN:
+      pv->data.v_int = punit->veteran;
+      break;
     default:
       freelog(LOG_ERROR, "Unhandled request for value of property %d "
               "(%s) from object of type \"%s\" in "
@@ -1533,6 +1560,36 @@ static bool objbind_get_allowed_value_span(struct objbind *ob,
       step = 1;
       big_step = 5;
       break;
+    case OPID_UNIT_FUEL:
+      min = 0;
+      max = putype->fuel;
+      step = 1;
+      big_step = 5;
+      break;
+    case OPID_UNIT_HP:
+      min = 1;
+      max = putype->hp;
+      step = 1;
+      big_step = 10;
+      break;
+    case OPID_UNIT_VETERAN:
+      min = 0;
+      if (unit_has_type_flag(punit, F_NO_VETERAN)) {
+        max = 0;
+      } else {
+        int i;
+        /* FIXME: The maximum veteran level is
+         * really not stored anywhere?? */
+        for (i = 1; i < MAX_VET_LEVELS; i++) {
+          if (putype->veteran[i].name[0] == '\0') {
+            break;
+          }
+        }
+        max = i - 1;
+      }
+      step = 1;
+      big_step = 3;
+      break;
     default:
       freelog(LOG_ERROR, "Unhandled request for value range of "
               "property %d (%s) from object of type \"%s\" in "
@@ -1843,6 +1900,11 @@ static void objbind_pack_current_values(struct objbind *ob,
 
     packet->id = punit->id;
     packet->moves_left = punit->moves_left;
+    packet->fuel = punit->fuel;
+    packet->moved = punit->moved;
+    packet->done_moving = punit->done_moving;
+    packet->hp = punit->hp;
+    packet->veteran = punit->veteran;
     /* TODO: Set more packet fields. */
 
   } else if (objtype == OBJTYPE_CITY) {
@@ -1955,6 +2017,21 @@ static void objbind_pack_modified_value(struct objbind *ob,
     case OPID_UNIT_MOVES_LEFT:
       packet->moves_left = pv->data.v_int;
       break;
+    case OPID_UNIT_FUEL:
+      packet->fuel = pv->data.v_int;
+      break;
+    case OPID_UNIT_MOVED:
+      packet->moved = pv->data.v_bool;
+      break;
+    case OPID_UNIT_DONE_MOVING:
+      packet->done_moving = pv->data.v_bool;
+      break;
+    case OPID_UNIT_HP:
+      packet->hp = pv->data.v_int;
+      break;
+    case OPID_UNIT_VETERAN:
+      packet->veteran = pv->data.v_int;
+      break;
     default:
       freelog(LOG_ERROR, "Unhandled request to pack value of "
               "property %d (%s) from object of type \"%s\" in "
@@ -2091,6 +2168,9 @@ static GType objprop_get_gtype(const struct objprop *op)
   case VALTYPE_INT:
     return G_TYPE_INT;
     break;
+  case VALTYPE_BOOL:
+    return G_TYPE_BOOLEAN;
+    break;
   case VALTYPE_STRING:
   case VALTYPE_BUILT_ARRAY:
   case VALTYPE_INVENTIONS_ARRAY:
@@ -2308,12 +2388,29 @@ static void objprop_widget_spin_button_changed(GtkSpinButton *spin,
 }
 
 /****************************************************************************
+  Callback for toggle type button widget 'toggled' signal.
+****************************************************************************/
+static void objprop_widget_toggle_button_changed(GtkToggleButton *button,
+                                                 gpointer userdata)
+{
+  struct objprop *op;
+  struct property_page *pp;
+  struct propval value = {{0,}, VALTYPE_BOOL, FALSE};
+
+  op = userdata;
+  pp = objprop_get_property_page(op);
+  value.data.v_bool = gtk_toggle_button_get_active(button);
+
+  property_page_change_value(pp, op, &value);
+}
+
+/****************************************************************************
   Create the gtk widget used to edit or display this object property.
 ****************************************************************************/
 static void objprop_setup_widget(struct objprop *op)
 {
   GtkWidget *w = NULL;
-  GtkWidget *hbox, *hbox2, *label, *image, *entry, *spin;
+  GtkWidget *hbox, *hbox2, *label, *image, *entry, *spin, *button;
   struct extviewer *ev = NULL;
   int propid;
 
@@ -2376,7 +2473,7 @@ static void objprop_setup_widget(struct objprop *op)
     entry = gtk_entry_new();
     gtk_entry_set_width_chars(GTK_ENTRY(entry), 8);
     g_signal_connect(entry, "activate",
-                     G_CALLBACK(objprop_widget_entry_activated), op);                     
+        G_CALLBACK(objprop_widget_entry_activated), op);
     gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
     objprop_set_child_widget(op, "entry", entry);
     break;
@@ -2386,18 +2483,21 @@ static void objprop_setup_widget(struct objprop *op)
   case OPID_GAME_YEAR:
     spin = gtk_spin_button_new_with_range(0.0, 100.0, 1.0);
     g_signal_connect(spin, "value-changed",
-                     G_CALLBACK(objprop_widget_spin_button_changed), op);
+        G_CALLBACK(objprop_widget_spin_button_changed), op);
     gtk_box_pack_start(GTK_BOX(hbox), spin, TRUE, TRUE, 0);
     objprop_set_child_widget(op, "spin", spin);
     break;
 
   case OPID_UNIT_MOVES_LEFT:
+  case OPID_UNIT_FUEL:
+  case OPID_UNIT_HP:
+  case OPID_UNIT_VETERAN:
   case OPID_CITY_FOOD_STOCK:
     hbox2 = gtk_hbox_new(FALSE, 4);
     gtk_box_pack_start(GTK_BOX(hbox), hbox2, TRUE, TRUE, 0);
     spin = gtk_spin_button_new_with_range(0.0, 100.0, 1.0);
     g_signal_connect(spin, "value-changed",
-                     G_CALLBACK(objprop_widget_spin_button_changed), op);
+        G_CALLBACK(objprop_widget_spin_button_changed), op);
     gtk_box_pack_start(GTK_BOX(hbox2), spin, TRUE, TRUE, 0);
     objprop_set_child_widget(op, "spin", spin);
     label = gtk_label_new(NULL);
@@ -2417,6 +2517,15 @@ static void objprop_setup_widget(struct objprop *op)
     property_page_add_extviewer(objprop_get_property_page(op), ev);
     break;
 
+  case OPID_UNIT_MOVED:
+  case OPID_UNIT_DONE_MOVING:
+    button = gtk_check_button_new();
+    g_signal_connect(button, "toggled",
+        G_CALLBACK(objprop_widget_toggle_button_changed), op);
+    gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+    objprop_set_child_widget(op, "checkbutton", button);
+    break;
+
   default:
     freelog(LOG_ERROR, "Unhandled request to create widget for "
             "property %d (%s) in objprop_setup_widget().",
@@ -2438,7 +2547,7 @@ static void objprop_setup_widget(struct objprop *op)
 static void objprop_refresh_widget(struct objprop *op,
                                    struct objbind *ob)
 {
-  GtkWidget *w, *label, *image, *entry, *spin;
+  GtkWidget *w, *label, *image, *entry, *spin, *button;
   struct extviewer *ev;
   struct propval *pv;
   bool modified;
@@ -2446,11 +2555,7 @@ static void objprop_refresh_widget(struct objprop *op,
   double min, max, step, big_step;
   char buf[256];
 
-  if (!op) {
-    return;
-  }
-
-  if (!objprop_has_widget(op)) {
+  if (!op || !objprop_has_widget(op)) {
     return;
   }
 
@@ -2567,6 +2672,9 @@ static void objprop_refresh_widget(struct objprop *op,
     break;
 
   case OPID_UNIT_MOVES_LEFT:
+  case OPID_UNIT_FUEL:
+  case OPID_UNIT_HP:
+  case OPID_UNIT_VETERAN:
   case OPID_CITY_FOOD_STOCK:
     spin = objprop_get_child_widget(op, "spin");
     label = objprop_get_child_widget(op, "max-value-label");
@@ -2604,6 +2712,22 @@ static void objprop_refresh_widget(struct objprop *op,
     }
     break;
 
+  case OPID_UNIT_MOVED:
+  case OPID_UNIT_DONE_MOVING:
+    button = objprop_get_child_widget(op, "checkbutton");
+    disable_widget_callback(button,
+        G_CALLBACK(objprop_widget_toggle_button_changed));
+    if (pv) {
+      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
+                                   pv->data.v_bool);
+    } else {
+      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
+    }
+    enable_widget_callback(button,
+        G_CALLBACK(objprop_widget_toggle_button_changed));
+    gtk_widget_set_sensitive(button, pv != NULL);
+    break;
+
   default:
     freelog(LOG_ERROR, "Widget refresh missing in "
             "objprop_refresh_widget() for objprop id=%d "
@@ -3326,6 +3450,17 @@ static void property_page_setup_objprops(struct property_page *pp)
             OPF_IN_LISTVIEW | OPF_HAS_WIDGET, VALTYPE_STRING);
     ADDPROP(OPID_UNIT_MOVES_LEFT, _("Moves Left"),
             OPF_IN_LISTVIEW | OPF_HAS_WIDGET | OPF_EDITABLE, VALTYPE_INT);
+    ADDPROP(OPID_UNIT_FUEL, _("Fuel"),
+            OPF_IN_LISTVIEW | OPF_HAS_WIDGET | OPF_EDITABLE, VALTYPE_INT);
+    ADDPROP(OPID_UNIT_MOVED, _("Moved"),
+            OPF_IN_LISTVIEW | OPF_HAS_WIDGET | OPF_EDITABLE, VALTYPE_BOOL);
+    ADDPROP(OPID_UNIT_DONE_MOVING, _("Done Moving"),
+            OPF_IN_LISTVIEW | OPF_HAS_WIDGET | OPF_EDITABLE, VALTYPE_BOOL);
+    /* TRANS: HP = Hit Points of a unit. */
+    ADDPROP(OPID_UNIT_HP, _("HP"),
+            OPF_IN_LISTVIEW | OPF_HAS_WIDGET | OPF_EDITABLE, VALTYPE_INT);
+    ADDPROP(OPID_UNIT_VETERAN, _("Veteran"),
+            OPF_IN_LISTVIEW | OPF_HAS_WIDGET | OPF_EDITABLE, VALTYPE_INT);
     break;
 
   case OBJTYPE_CITY:
@@ -3926,6 +4061,7 @@ static bool property_page_set_store_value(struct property_page *pp,
   int valtype;
   char buf[128];
   GdkPixbuf *pixbuf = NULL;
+  GtkListStore *store;
 
   if (!pp || !pp->object_store || !op || !ob) {
     return FALSE;
@@ -3946,26 +4082,30 @@ static bool property_page_set_store_value(struct property_page *pp,
   }
 
   valtype = objprop_get_valtype(op);
+  store = pp->object_store;
 
   switch (valtype) {
   case VALTYPE_INT:
-    gtk_list_store_set(pp->object_store, iter, col_id, pv->data.v_int, -1);
+    gtk_list_store_set(store, iter, col_id, pv->data.v_int, -1);
+    break;
+  case VALTYPE_BOOL:
+    gtk_list_store_set(store, iter, col_id, pv->data.v_bool, -1);
     break;
   case VALTYPE_STRING:
-    gtk_list_store_set(pp->object_store, iter, col_id, pv->data.v_string, -1);
+    gtk_list_store_set(store, iter, col_id, pv->data.v_string, -1);
     break;
   case VALTYPE_PIXBUF:
-    gtk_list_store_set(pp->object_store, iter, col_id, pv->data.v_pixbuf, -1);
+    gtk_list_store_set(store, iter, col_id, pv->data.v_pixbuf, -1);
     break;
   case VALTYPE_BUILT_ARRAY:
   case VALTYPE_INVENTIONS_ARRAY:
   case VALTYPE_BV_SPECIAL:
     propval_as_string(pv, buf, sizeof(buf));
-    gtk_list_store_set(pp->object_store, iter, col_id, buf, -1);
+    gtk_list_store_set(store, iter, col_id, buf, -1);
     break;
   case VALTYPE_NATION:
     pixbuf = get_flag(pv->data.v_nation);
-    gtk_list_store_set(pp->object_store, iter, col_id, pixbuf, -1);
+    gtk_list_store_set(store, iter, col_id, pixbuf, -1);
     if (pixbuf) {
       g_object_unref(pixbuf);
     }
diff --git a/common/packets.def b/common/packets.def
index fdbfea1..e24a755 100644
--- a/common/packets.def
+++ b/common/packets.def
@@ -1523,6 +1523,7 @@ PACKET_EDIT_UNIT=164;cs,handle-per-conn,handle-via-packet
   BOOL debug;
   BOOL moved;
   BOOL paradropped;
+  BOOL done_moving;
   UNIT transported_by;
 end
 
diff --git a/server/edithand.c b/server/edithand.c
index a17a88d..aefccd4 100644
--- a/server/edithand.c
+++ b/server/edithand.c
@@ -544,12 +544,12 @@ void handle_edit_unit(struct connection *pc,
                       struct packet_edit_unit *packet)
 {
   struct tile *ptile;
-  struct unit_type *punittype;
+  struct unit_type *putype;
   struct player *pplayer;
   struct unit *punit;
   int id;
   bool changed = FALSE;
-  int moves_left;
+  int moves_left, fuel, hp;
 
   if (!can_conn_edit(pc)) {
     notify_conn(pc->self, NULL, E_BAD_COMMAND,
@@ -566,16 +566,49 @@ void handle_edit_unit(struct connection *pc,
   }
 
   ptile = unit_tile(punit);
-  punittype = unit_type(punit);
+  putype = unit_type(punit);
   pplayer = unit_owner(punit);
 
-  /* Handle a change in the number of moves left. */
-  moves_left = CLIP(0, packet->moves_left, punittype->move_rate);
+  moves_left = CLIP(0, packet->moves_left, putype->move_rate);
   if (moves_left != punit->moves_left) {
     punit->moves_left = moves_left;
     changed = TRUE;
   }
 
+  fuel = CLIP(0, packet->fuel, putype->fuel);
+  if (fuel != punit->fuel) {
+    punit->fuel = fuel;
+    changed = TRUE;
+  }
+
+  if (packet->moved != punit->moved) {
+    punit->moved = packet->moved;
+    changed = TRUE;
+  }
+
+  if (packet->done_moving != punit->done_moving) {
+    punit->done_moving = packet->done_moving;
+    changed = TRUE;
+  }
+
+  hp = CLIP(1, packet->hp, putype->hp);
+  if (hp != punit->hp) {
+    punit->hp = hp;
+    changed = TRUE;
+  }
+
+  if (packet->veteran != punit->veteran
+      && !unit_has_type_flag(punit, F_NO_VETERAN)) {
+    int v = packet->veteran;
+    if (putype->veteran[v].name[0] == '\0') {
+      notify_conn(pc->self, NULL, E_BAD_COMMAND,
+                  _("Invalid veteran level %d for unit %d (%s)."),
+                  v, id, unit_name_translation(punit));
+    } else {
+      punit->veteran = v;
+      changed = TRUE;
+    }
+  }
 
   /* TODO: Handle more property edits. */
 
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to