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

 This adds special pillage target S_PILLAGE_BASE.


 - ML

diff -Nurd -X.diff_ignore freeciv/client/control.c freeciv/client/control.c
--- freeciv/client/control.c	2007-03-14 13:15:03.000000000 +0200
+++ freeciv/client/control.c	2007-03-15 11:59:50.000000000 +0200
@@ -1484,6 +1484,7 @@
   bv_special pspresent = get_tile_infrastructure_set(ptile, NULL);
   bv_special psworking = get_unit_tile_pillage_set(punit->tile);
   bv_special pspossible;
+  struct base_type *pbase = tile_get_base(punit->tile);
   int count = 0;
   enum tile_special_type spe;
 
@@ -1495,10 +1496,10 @@
     }
   }
 
-  if (count > 1) {
-    popup_pillage_dialog(punit, pspossible);
+  if (count > 1 || pbase) {
+    popup_pillage_dialog(punit, pspossible, pbase);
   } else {
-    enum tile_special_type what = get_preferred_pillage(pspossible);
+    enum tile_special_type what = get_preferred_pillage(pspossible, NULL);
 
     request_new_unit_activity_targeted(punit, ACTIVITY_PILLAGE, what);
   }
diff -Nurd -X.diff_ignore freeciv/client/gui-gtk-2.0/dialogs.c freeciv/client/gui-gtk-2.0/dialogs.c
--- freeciv/client/gui-gtk-2.0/dialogs.c	2007-03-05 21:11:59.000000000 +0200
+++ freeciv/client/gui-gtk-2.0/dialogs.c	2007-03-15 11:56:59.000000000 +0200
@@ -298,7 +298,8 @@
 ...
 *****************************************************************/
 void popup_pillage_dialog(struct unit *punit,
-			  bv_special may_pillage)
+			  bv_special may_pillage,
+                          struct base_type *pbase)
 {
   GtkWidget *shl;
   enum tile_special_type what, prereq;
@@ -311,18 +312,25 @@
 			       _("What To Pillage"),
 			       _("Select what to pillage:"));
 
-    while ((what = get_preferred_pillage(may_pillage)) != S_LAST) {
+    while ((what = get_preferred_pillage(may_pillage, pbase)) != S_LAST) {
       bv_special what_bv;
 
-      BV_CLR_ALL(what_bv);
-      BV_SET(what_bv, what);
-      choice_dialog_add(shl, get_infrastructure_text(what_bv),
-			G_CALLBACK(pillage_callback), GINT_TO_POINTER(what));
+      if (what != S_PILLAGE_BASE) {
+        BV_CLR_ALL(what_bv);
+        BV_SET(what_bv, what);
+        choice_dialog_add(shl, get_infrastructure_text(what_bv),
+                          G_CALLBACK(pillage_callback), GINT_TO_POINTER(what));
 
-      clear_special(&may_pillage, what);
-      prereq = get_infrastructure_prereq(what);
-      if (prereq != S_LAST) {
-	clear_special(&may_pillage, prereq);
+        clear_special(&may_pillage, what);
+        prereq = get_infrastructure_prereq(what);
+        if (prereq != S_LAST) {
+          clear_special(&may_pillage, prereq);
+        }
+      } else {
+        choice_dialog_add(shl, base_name(pbase),
+                          G_CALLBACK(pillage_callback),
+                          GINT_TO_POINTER(S_PILLAGE_BASE));
+        pbase = NULL;
       }
     }
 
diff -Nurd -X.diff_ignore freeciv/client/gui-sdl/dialogs.c freeciv/client/gui-sdl/dialogs.c
--- freeciv/client/gui-sdl/dialogs.c	2007-03-08 18:42:40.000000000 +0200
+++ freeciv/client/gui-sdl/dialogs.c	2007-03-15 12:06:05.000000000 +0200
@@ -1720,7 +1720,8 @@
   pillage.
 **************************************************************************/
 void popup_pillage_dialog(struct unit *pUnit,
-			  bv_special may_pillage)
+			  bv_special may_pillage,
+                          struct base_type *pbase)
 {
   struct widget *pWindow = NULL, *pBuf = NULL;
   SDL_String16 *pStr;
@@ -1762,15 +1763,27 @@
   add_to_gui_list(ID_PILLAGE_DLG_EXIT_BUTTON, pBuf);
   /* ---------- */
   
-  while ((what = get_preferred_pillage(may_pillage)) != S_LAST) {
+  while ((what = get_preferred_pillage(may_pillage, pbase)) != S_LAST) {
       
     bv_special what_bv;
-      
-    BV_CLR_ALL(what_bv);
-    BV_SET(what_bv, what);
+
+    if (what != S_PILLAGE_BASE) {
+      BV_CLR_ALL(what_bv);
+      BV_SET(what_bv, what);
     
-    create_active_iconlabel(pBuf, pWindow->dst, pStr,
-	    (char *) get_special_name(what), pillage_callback);
+      create_active_iconlabel(pBuf, pWindow->dst, pStr,
+                              (char *) get_special_name(what), pillage_callback);
+      clear_special(&may_pillage, what);
+      prereq = get_infrastructure_prereq(what);
+      if (prereq != S_LAST) {
+        clear_special(&may_pillage, prereq);  
+      }
+    } else {
+      create_active_iconlabel(pBuf, pWindow->dst, pStr,
+                              (char *) base_name(pbase), pillage_callback);
+      pbase = NULL;
+    }
+
     pBuf->data.unit = pUnit;
     set_wstate(pBuf, FC_WS_NORMAL);
   
@@ -1778,12 +1791,6 @@
     
     area.w = MAX(area.w, pBuf->size.w);
     area.h += pBuf->size.h;
-        
-    clear_special(&may_pillage, what);
-    prereq = get_infrastructure_prereq(what);
-    if (prereq != S_LAST) {
-      clear_special(&may_pillage, prereq);  
-    }
   }
   pPillage_Dlg->pBeginWidgetList = pBuf;
 
diff -Nurd -X.diff_ignore freeciv/client/gui-stub/dialogs.c freeciv/client/gui-stub/dialogs.c
--- freeciv/client/gui-stub/dialogs.c	2007-03-05 21:12:21.000000000 +0200
+++ freeciv/client/gui-stub/dialogs.c	2007-03-15 12:21:00.000000000 +0200
@@ -145,7 +145,8 @@
   Popup a dialog asking the unit which improvement they would like to
   pillage.
 **************************************************************************/
-void popup_pillage_dialog(struct unit *punit, bv_special may_pillage)
+void popup_pillage_dialog(struct unit *punit, bv_special may_pillage,
+                          struct base_type *pbase)
 {
   /* PORTME */
 }
diff -Nurd -X.diff_ignore freeciv/client/gui-xaw/dialogs.c freeciv/client/gui-xaw/dialogs.c
--- freeciv/client/gui-xaw/dialogs.c	2007-03-05 21:12:03.000000000 +0200
+++ freeciv/client/gui-xaw/dialogs.c	2007-03-15 12:20:34.000000000 +0200
@@ -544,7 +544,8 @@
 ...
 *****************************************************************/
 void popup_pillage_dialog(struct unit *punit,
-			  bv_special may_pillage)
+			  bv_special may_pillage,
+                          struct base_type *pbase)
 {
   Widget shell, form, dlabel, button, prev;
   enum tile_special_type what, prereq;
@@ -563,25 +564,36 @@
   dlabel = I_L(XtVaCreateManagedWidget("dlabel", labelWidgetClass, form, NULL));
 
   prev = dlabel;
-  while ((what = get_preferred_pillage(may_pillage)) != S_LAST) {
+  while ((what = get_preferred_pillage(may_pillage, pbase)) != S_LAST) {
     bv_special what_bv;
 
-    BV_CLR_ALL(what_bv);
-    BV_SET(what_bv, what);
-    button =
-      XtVaCreateManagedWidget ("button", commandWidgetClass, form,
-			       XtNfromVert, prev,
-			       XtNlabel,
-			       (XtArgVal)(get_infrastructure_text(what_bv)),
-			       NULL);
-    XtAddCallback(button, XtNcallback, pillage_callback,
-		  INT_TO_XTPOINTER(what));
-    prev = button;
-    clear_special(&may_pillage, what);
-    prereq = get_infrastructure_prereq(what);
-    if (prereq != S_LAST) {
-      clear_special(&may_pillage, prereq);
+    if (what != S_PILLAGE_BASE) {
+      BV_CLR_ALL(what_bv);
+      BV_SET(what_bv, what);
+      button =
+        XtVaCreateManagedWidget ("button", commandWidgetClass, form,
+                                 XtNfromVert, prev,
+                                 XtNlabel,
+                                 (XtArgVal)(get_infrastructure_text(what_bv)),
+                                 NULL);
+      XtAddCallback(button, XtNcallback, pillage_callback,
+                    INT_TO_XTPOINTER(what));
+      clear_special(&may_pillage, what);
+      prereq = get_infrastructure_prereq(what);
+      if (prereq != S_LAST) {
+        clear_special(&may_pillage, prereq);
+      }
+    } else {
+      button =
+        XtVaCreateManagedWidget ("button", commandWidgetClass, form,
+                                 XtNfromVert, prev,
+                                 XtNlabel,
+                                 (XtArgVal)(base_name(pbase)),
+                                 NULL);
+      XtAddCallback(button, XtNcallback, pillage_callback,
+                    INT_TO_XTPOINTER(S_PILLAGE_BASE));
     }
+    prev = button;
   }
   button =
     I_L(XtVaCreateManagedWidget("closebutton", commandWidgetClass, form,
diff -Nurd -X.diff_ignore freeciv/client/include/dialogs_g.h freeciv/client/include/dialogs_g.h
--- freeciv/client/include/dialogs_g.h	2007-03-05 21:12:04.000000000 +0200
+++ freeciv/client/include/dialogs_g.h	2007-03-15 11:57:41.000000000 +0200
@@ -44,7 +44,8 @@
 void popup_incite_dialog(struct city *pcity);
 void popup_bribe_dialog(struct unit *punit);
 void popup_sabotage_dialog(struct city *pcity);
-void popup_pillage_dialog(struct unit *punit, bv_special may_pillage);
+void popup_pillage_dialog(struct unit *punit, bv_special may_pillage,
+                          struct base_type *pbase);
 void popup_upgrade_dialog(struct unit_list *punits);
 
 void popdown_all_game_dialogs(void);
diff -Nurd -X.diff_ignore freeciv/common/terrain.c freeciv/common/terrain.c
--- freeciv/common/terrain.c	2007-03-05 21:11:49.000000000 +0200
+++ freeciv/common/terrain.c	2007-03-15 11:44:58.000000000 +0200
@@ -522,10 +522,11 @@
 
 /****************************************************************************
   Returns the highest-priority (best) infrastructure (man-made special) to
-  be pillaged from the terrain set.  May return S_NO_SPECIAL if nothing
+  be pillaged from the terrain set.  May return S_LAST if nothing
   better is available.
 ****************************************************************************/
-enum tile_special_type get_preferred_pillage(bv_special pset)
+enum tile_special_type get_preferred_pillage(bv_special pset,
+                                             struct base_type *pbase)
 {
   if (contains_special(pset, S_FARMLAND)) {
     return S_FARMLAND;
@@ -536,11 +537,8 @@
   if (contains_special(pset, S_MINE)) {
     return S_MINE;
   }
-  if (contains_special(pset, S_FORTRESS)) {
-    return S_FORTRESS;
-  }
-  if (contains_special(pset, S_AIRBASE)) {
-    return S_AIRBASE;
+  if (pbase) {
+    return S_PILLAGE_BASE;
   }
   if (contains_special(pset, S_RAILROAD)) {
     return S_RAILROAD;
diff -Nurd -X.diff_ignore freeciv/common/terrain.h freeciv/common/terrain.h
--- freeciv/common/terrain.h	2007-03-05 21:11:49.000000000 +0200
+++ freeciv/common/terrain.h	2007-03-15 12:35:30.000000000 +0200
@@ -19,6 +19,7 @@
 
 #include "unittype.h"
 
+struct base_type;
 
 enum special_river_move {
   RMV_NORMAL=0, RMV_FAST_STRICT=1, RMV_FAST_RELAXED=2, RMV_FAST_ALWAYS=3
@@ -39,6 +40,9 @@
   S_LAST
 };
 
+/* Special value for pillaging bases */
+#define S_PILLAGE_BASE (S_LAST + 1)
+
 enum terrain_class { TC_LAND, TC_OCEAN, TC_LAST };
 
 /* S_LAST-terminated */
@@ -246,7 +250,8 @@
 /* Special helper functions */
 const char *get_infrastructure_text(bv_special pset);
 enum tile_special_type get_infrastructure_prereq(enum tile_special_type spe);
-enum tile_special_type get_preferred_pillage(bv_special pset);
+enum tile_special_type get_preferred_pillage(bv_special pset,
+                                             struct base_type *pbase);
 
 /* Terrain-specific functions. */
 #define is_ocean(pterrain) ((pterrain) != T_UNKNOWN			    \
diff -Nurd -X.diff_ignore freeciv/common/unit.c freeciv/common/unit.c
--- freeciv/common/unit.c	2007-03-12 16:23:02.000000000 +0200
+++ freeciv/common/unit.c	2007-03-15 12:35:11.000000000 +0200
@@ -875,6 +875,7 @@
     {
       int numpresent;
       bv_special pspresent = get_tile_infrastructure_set(ptile, &numpresent);
+      old_base = tile_get_base(ptile);
 
       if (numpresent > 0 && is_ground_unit(punit)) {
 	bv_special psworking;
@@ -898,10 +899,15 @@
 	    }
 	  }
 	} else if (!game.info.pillage_select
-		   && target != get_preferred_pillage(pspresent)) {
+		   && target != get_preferred_pillage(pspresent,
+                                                      tile_get_base(ptile))) {
 	  return FALSE;
 	} else {
-	  return BV_ISSET(pspresent, target) && !BV_ISSET(psworking, target);
+          if (target == S_PILLAGE_BASE) {
+            return old_base != NULL;
+          } else {
+            return BV_ISSET(pspresent, target) && !BV_ISSET(psworking, target);
+          }
 	}
       } else {
 	return FALSE;
diff -Nurd -X.diff_ignore freeciv/server/savegame.c freeciv/server/savegame.c
--- freeciv/server/savegame.c	2007-03-14 17:53:41.000000000 +0200
+++ freeciv/server/savegame.c	2007-03-15 12:24:34.000000000 +0200
@@ -1728,6 +1728,12 @@
       = secfile_lookup_int_default(file, S_LAST,
 				   "player%d.u%d.activity_target", plrno, i);
 
+    if (activity == ACTIVITY_PILLAGE
+        && (punit->activity_target == S_FORTRESS
+            || punit->activity_target == S_AIRBASE)) {
+      punit->activity_target = S_PILLAGE_BASE;
+    }
+
     punit->done_moving = secfile_lookup_bool_default(file,
 	(punit->moves_left == 0), "player%d.u%d.done_moving", plrno, i);
 
diff -Nurd -X.diff_ignore freeciv/server/unittools.c freeciv/server/unittools.c
--- freeciv/server/unittools.c	2007-03-12 16:23:02.000000000 +0200
+++ freeciv/server/unittools.c	2007-03-15 11:52:14.000000000 +0200
@@ -661,10 +661,15 @@
     if (punit->activity_target == S_LAST) { /* case for old save files */
       if (punit->activity_count >= 1) {
 	enum tile_special_type what
-	  = get_preferred_pillage(get_tile_infrastructure_set(ptile, NULL));
+	  = get_preferred_pillage(get_tile_infrastructure_set(ptile, NULL),
+                                  tile_get_base(ptile));
 
 	if (what != S_LAST) {
-	  tile_clear_special(ptile, what);
+          if (what == S_PILLAGE_BASE) {
+            tile_remove_base(ptile);
+          } else {
+            tile_clear_special(ptile, what);
+          }
 	  update_tile_knowledge(ptile);
 	  set_unit_activity(punit, ACTIVITY_IDLE);
 	  check_adjacent_units = TRUE;
@@ -678,7 +683,7 @@
                                      punit->activity_target) >= 1) {
       enum tile_special_type what_pillaged = punit->activity_target;
 
-      if (what_pillaged == S_FORTRESS || what_pillaged == S_AIRBASE) {
+      if (what_pillaged == S_PILLAGE_BASE) {
         tile_remove_base(ptile);
       } else {
         tile_clear_special(ptile, what_pillaged);
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to