Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2003:
[Freeciv-Dev] Team research (PR#4213)
Home

[Freeciv-Dev] Team research (PR#4213)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: ue80@xxxxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] Team research (PR#4213)
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Tue, 16 Sep 2003 08:31:38 -0700
Reply-to: rt@xxxxxxxxxxxxxx

This patch is an adaptation of the earlier 'union pact' patch. It now only
works for teams. It is on by default, but you can opt out of the research
pool to pursue individual research, and later rejoin the research pool
too.

The reason this is not available for non-team games: It makes diplomacy
too powerful. While it is already powerful, this feature is really a game
winner. Every game would be about getting research pools set up as fast as
possible and with as many as possible. Or at least that's what I suspect.

Both gtk1 and gtk2 clients are fully supported. Other clients are somewhat
supported but lack some features. These will be completed once/if the
design board has approved this patch. Only the gtk2 client has been
tested.

  - Per

? teamresearch1.diff
? union3.diff
? union4.diff
? union5.diff
? data/test
Index: ai/advdiplomacy.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/advdiplomacy.c,v
retrieving revision 1.4
diff -u -r1.4 advdiplomacy.c
--- ai/advdiplomacy.c   2003/08/25 11:30:15     1.4
+++ ai/advdiplomacy.c   2003/09/16 15:23:26
@@ -201,6 +201,10 @@
     } players_iterate_end;
   break;
 
+  case CLAUSE_TEAM:
+    worth = 1;
+    break;
+
   case CLAUSE_ALLIANCE:
   case CLAUSE_PEACE:
   case CLAUSE_CEASEFIRE:
@@ -500,7 +504,7 @@
    * he or she offers us gifts. It is only a gift if _all_ the clauses
    * are beneficial to us. */
   if (total_balance > 0 && gift) {
-    int i = total_balance / (city_list_size(&pplayer->cities) * 50) + 1;
+    int i = total_balance / ((city_list_size(&pplayer->cities) * 50) + 1);
 
     i = MIN(i, ai->diplomacy.love_incr * 150);
     adip->love += i;
@@ -992,6 +996,9 @@
     }
 
     switch (ds) {
+    case DS_TEAM:
+      ai_share_techs(pplayer, aplayer);
+      break;
     case DS_ALLIANCE:
       if ((pplayer->team != TEAM_NONE && aplayer->team == pplayer->team)
           || (target && (!pplayers_at_war(pplayer, target)
Index: client/climisc.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/climisc.c,v
retrieving revision 1.120
diff -u -r1.120 climisc.c
--- client/climisc.c    2003/08/06 07:22:44     1.120
+++ client/climisc.c    2003/09/16 15:23:26
@@ -276,12 +276,18 @@
   case CLAUSE_ALLIANCE:
     my_snprintf(buf, bufsiz, _("The parties create an alliance"));
     break;
+  case CLAUSE_TEAM:
+    my_snprintf(buf, bufsiz, _("The parties resume the research pool"));
+    break;
   case CLAUSE_VISION:
     my_snprintf(buf, bufsiz, _("The %s gives shared vision"),
                get_nation_name_plural(pclause->from->nation));
     break;
   default:
-    if (bufsiz > 0) *buf = '\0';
+    assert(FALSE);
+    if (bufsiz > 0) {
+      *buf = '\0';
+    }
     break;
   }
 }
@@ -1169,4 +1175,37 @@
                name, value, game.player_ptr->economic.gold);
     append_output_window(buf);
   }
+}
+
+/**************************************************************************
+  Returns the text to display in the science dialog.
+**************************************************************************/
+const char *science_dialog_text()
+{
+  int turns_to_advance;
+  static char text[512];
+
+  turns_to_advance = tech_turns_to_advance(game.player_ptr);
+  if (turns_to_advance == FC_INFINITY) {
+    my_snprintf(text, sizeof(text), _("Progress: no research"));
+  } else if (game.player_ptr->research.bulbs_last_turn
+             == game.player_ptr->research.bulbs_last_turn_techpool) {
+    /* Simple version, no techpool */
+    my_snprintf(text, sizeof(text),
+                PL_("Progress: %d turn/advance (%d pts/turn)",
+                    "Progress: %d turns/advance (%d pts/turn)",
+                    turns_to_advance),
+                turns_to_advance, game.player_ptr->research.bulbs_last_turn);
+  } else {
+    /* Techpool version */
+    my_snprintf(text, sizeof(text),
+                PL_("Progress: %d turn/advance (%d pts/turn, "
+                    "%d pts/turn techpool)",
+                    "Progress: %d turns/advance (%d pts/turn, "
+                    "%d pts/turn techpool)",
+                    turns_to_advance),
+                turns_to_advance, game.player_ptr->research.bulbs_last_turn,
+                game.player_ptr->research.bulbs_last_turn_techpool);
+  }
+  return text;
 }
Index: client/climisc.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/climisc.h,v
retrieving revision 1.44
diff -u -r1.44 climisc.h
--- client/climisc.h    2003/02/15 20:26:17     1.44
+++ client/climisc.h    2003/09/16 15:23:26
@@ -121,6 +121,7 @@
                            char *buf, size_t bufsz);
 
 const char *unit_description(struct unit *punit);
+const char *science_dialog_text(void);
 
 void cityrep_buy(struct city *pcity);
 
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.330
diff -u -r1.330 packhand.c
--- client/packhand.c   2003/09/15 19:40:52     1.330
+++ client/packhand.c   2003/09/16 15:23:26
@@ -1445,10 +1445,12 @@
                || pplayer->ai.tech_goal != pinfo->tech_goal);
   pplayer->research.bulbs_researched = pinfo->bulbs_researched;
   pplayer->research.techs_researched = pinfo->techs_researched;
-  pplayer->research.researching=pinfo->researching;
-  pplayer->future_tech=pinfo->future_tech;
-  pplayer->ai.tech_goal=pinfo->tech_goal;
-  
+  pplayer->research.researching = pinfo->researching;
+  pplayer->future_tech = pinfo->future_tech;
+  pplayer->ai.tech_goal = pinfo->tech_goal;
+  pplayer->research.bulbs_last_turn = pinfo->bulbs_last_turn;
+  pplayer->research.bulbs_last_turn_techpool = pinfo->bulbs_last_turn_techpool;
+
   if (can_client_change_view() && pplayer == game.player_ptr) {
     if (poptechup || new_tech) {
       science_dialog_update();
Index: client/gui-gtk/diplodlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/diplodlg.c,v
retrieving revision 1.40
diff -u -r1.40 diplodlg.c
--- client/gui-gtk/diplodlg.c   2003/06/26 23:03:12     1.40
+++ client/gui-gtk/diplodlg.c   2003/09/16 15:23:26
@@ -114,6 +114,7 @@
 static void diplomacy_dialog_ceasefire_callback(GtkWidget *w, gpointer data);
 static void diplomacy_dialog_peace_callback(GtkWidget *w, gpointer data);
 static void diplomacy_dialog_alliance_callback(GtkWidget *w, gpointer data);
+static void diplomacy_dialog_team_callback(GtkWidget *w, gpointer data);
 static void diplomacy_dialog_vision_callback(GtkWidget *w, gpointer data);
 static void close_diplomacy_dialog(struct Diplomacy_dialog *pdialog);
 static void update_diplomacy_dialog(struct Diplomacy_dialog *pdialog);
@@ -473,6 +474,19 @@
   gtk_signal_connect(GTK_OBJECT(item),"activate",
        GTK_SIGNAL_FUNC(diplomacy_dialog_alliance_callback),(gpointer)pdialog);
 
+  if (plr0->team != TEAM_NONE && plr0->team == plr1->team) {
+    const struct player_diplstate *ds = pplayer_get_diplstate(plr0, plr1);
+
+    item = gtk_menu_item_new_with_label(Q_("?diplomatic_state:Team"));
+    gtk_menu_append(GTK_MENU(pdialog->dip_pact_menu), item);
+    g_signal_connect(GTK_OBJECT(item), "activate",
+                     G_SIGNAL_FUNC(diplomacy_dialog_team_callback), 
+                     (gpointer)pdialog);
+    if (ds->type == DS_TEAM) {
+      gtk_widget_set_sensitive(item, FALSE);
+    }
+  }
+
   gtk_widget_show_all(pdialog->dip_pact_menu);
 
   button=gtk_button_new_with_label(_("Pacts"));
@@ -777,6 +791,14 @@
 static void diplomacy_dialog_alliance_callback(GtkWidget *w, gpointer data)
 {
   diplomacy_dialog_add_pact_clause(w, data, CLAUSE_ALLIANCE);
+}
+
+/****************************************************************
+...
+*****************************************************************/
+static void diplomacy_dialog_team_callback(GtkWidget *w, gpointer data)
+{
+  diplomacy_dialog_add_pact_clause(w, data, CLAUSE_TEAM);
 }
 
 /****************************************************************
Index: client/gui-gtk/plrdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/plrdlg.c,v
retrieving revision 1.49
diff -u -r1.49 plrdlg.c
--- client/gui-gtk/plrdlg.c     2003/07/23 13:46:02     1.49
+++ client/gui-gtk/plrdlg.c     2003/09/16 15:23:26
@@ -460,6 +460,7 @@
        state_col = colors_standard[COLOR_STD_RED];
        break;
       case DS_ALLIANCE:
+      case DS_TEAM:
        state_col = colors_standard[COLOR_STD_GROUND];
        break;
       default:
Index: client/gui-gtk/repodlgs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/repodlgs.c,v
retrieving revision 1.73
diff -u -r1.73 repodlgs.c
--- client/gui-gtk/repodlgs.c   2003/09/15 19:40:52     1.73
+++ client/gui-gtk/repodlgs.c   2003/09/16 15:23:26
@@ -31,6 +31,7 @@
 #include "support.h"
 
 #include "civclient.h"
+#include "climisc.h"
 #include "clinet.h"
 #include "repodlgs_common.h"
 
@@ -375,22 +376,13 @@
   GtkWidget *item;
   GList *sorting_list = NULL;
   gfloat pct;
-  int turns_to_advance;
   int steps;
 
-  if(is_report_dialogs_frozen()) return;
-
-  turns_to_advance = tech_turns_to_advance(game.player_ptr);
-  if (turns_to_advance == FC_INFINITY) {
-    my_snprintf(text, sizeof(text), _("Research speed: no research"));
-  } else {
-    my_snprintf(text, sizeof(text),
-               PL_("Research speed: %d turn/advance",
-                   "Research speed: %d turns/advance", turns_to_advance),
-               turns_to_advance);
+  if (is_report_dialogs_frozen()) {
+    return;
   }
 
-  gtk_set_label(science_label, text);
+  gtk_set_label(science_label, science_dialog_text());
 
   for (i=0; i<4; i++) {
     gtk_clist_freeze(GTK_CLIST(science_list[i]));
Index: client/gui-gtk-2.0/diplodlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/diplodlg.c,v
retrieving revision 1.14
diff -u -r1.14 diplodlg.c
--- client/gui-gtk-2.0/diplodlg.c       2003/08/29 23:43:34     1.14
+++ client/gui-gtk-2.0/diplodlg.c       2003/09/16 15:23:26
@@ -87,6 +87,7 @@
 static void diplomacy_dialog_ceasefire_callback(GtkWidget *w, gpointer data);
 static void diplomacy_dialog_peace_callback(GtkWidget *w, gpointer data);
 static void diplomacy_dialog_alliance_callback(GtkWidget *w, gpointer data);
+static void diplomacy_dialog_team_callback(GtkWidget *w, gpointer data);
 static void diplomacy_dialog_vision_callback(GtkWidget *w, gpointer data);
 static void close_diplomacy_dialog(struct Diplomacy_dialog *pdialog);
 static void update_diplomacy_dialog(struct Diplomacy_dialog *pdialog);
@@ -347,6 +348,18 @@
     g_signal_connect(item, "activate",
                     G_CALLBACK(diplomacy_dialog_alliance_callback), pdialog);
 
+    if (plr0->team != TEAM_NONE && plr0->team == plr1->team) {
+      const struct player_diplstate *ds = pplayer_get_diplstate(plr0, plr1);
+
+      item = gtk_menu_item_new_with_mnemonic(Q_("?diplomatic_state:Team"));
+      gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+      g_signal_connect(item, "activate",
+                       G_CALLBACK(diplomacy_dialog_team_callback), pdialog);
+      if (ds->type == DS_TEAM) {
+        gtk_widget_set_sensitive(item, FALSE);
+      }
+    }
+
     item = gtk_menu_item_new_with_mnemonic(_("_Pacts"));
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
     gtk_menu_shell_append(GTK_MENU_SHELL(parent), item);
@@ -776,6 +789,14 @@
 static void diplomacy_dialog_alliance_callback(GtkWidget *w, gpointer data)
 {
   diplomacy_dialog_add_pact_clause(w, data, CLAUSE_ALLIANCE);
+}
+
+/****************************************************************
+...
+*****************************************************************/
+static void diplomacy_dialog_team_callback(GtkWidget *w, gpointer data)
+{
+  diplomacy_dialog_add_pact_clause(w, data, CLAUSE_TEAM);
 }
 
 /****************************************************************
Index: client/gui-gtk-2.0/plrdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/plrdlg.c,v
retrieving revision 1.28
diff -u -r1.28 plrdlg.c
--- client/gui-gtk-2.0/plrdlg.c 2003/07/23 13:46:02     1.28
+++ client/gui-gtk-2.0/plrdlg.c 2003/09/16 15:23:26
@@ -484,6 +484,7 @@
      state_col = colors_standard[COLOR_STD_RED];
      break;
    case DS_ALLIANCE:
+   case DS_TEAM:
      state_col = colors_standard[COLOR_STD_GROUND];
      break;
    default:
Index: client/gui-gtk-2.0/repodlgs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/repodlgs.c,v
retrieving revision 1.34
diff -u -r1.34 repodlgs.c
--- client/gui-gtk-2.0/repodlgs.c       2003/09/15 19:40:52     1.34
+++ client/gui-gtk-2.0/repodlgs.c       2003/09/16 15:23:26
@@ -32,6 +32,7 @@
 
 #include "cityrep.h"
 #include "civclient.h"
+#include "climisc.h"
 #include "clinet.h"
 #include "dialogs.h"
 #include "gui_main.h"
@@ -375,27 +376,18 @@
 void science_dialog_update(void)
 {
   if(science_dialog_shell) {
-  char text[512];
   int i, j, hist;
+  char text[512];
   GtkWidget *item;
   GList *sorting_list = NULL;
   gdouble pct;
-  int turns_to_advance;
   int steps;
-
-  if(is_report_dialogs_frozen()) return;
 
-  turns_to_advance = tech_turns_to_advance(game.player_ptr);
-  if (turns_to_advance == FC_INFINITY) {
-    my_snprintf(text, sizeof(text), _("Research speed: no research"));
-  } else {
-    my_snprintf(text, sizeof(text),
-               PL_("Research speed: %d turn/advance",
-                   "Research speed: %d turns/advance", turns_to_advance),
-               turns_to_advance);
+  if (is_report_dialogs_frozen()) {
+    return;
   }
 
-  gtk_set_label(science_label, text);
+  gtk_set_label(science_label, (char *)science_dialog_text());
 
   for (i=0; i<4; i++) {
     gtk_list_store_clear(science_model[i]);
Index: client/gui-win32/repodlgs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/repodlgs.c,v
retrieving revision 1.31
diff -u -r1.31 repodlgs.c
--- client/gui-win32/repodlgs.c 2003/09/15 19:40:52     1.31
+++ client/gui-win32/repodlgs.c 2003/09/16 15:23:26
@@ -33,6 +33,7 @@
  
 #include "cityrep.h"
 #include "civclient.h"
+#include "climisc.h"
 #include "dialogs.h"
 #include "gui_stuff.h"
 #include "gui_main.h"
@@ -97,15 +98,7 @@
   if (!science_dlg) return;            
   report_title=get_report_title(_("Science"));
   sz_strlcpy(text, report_title);
-  turns_to_advance = tech_turns_to_advance(game.player_ptr);
-  if (turns_to_advance == FC_INFINITY) {
-    my_snprintf(rate, sizeof(rate), _("\n(no research)"));
-  } else {
-    my_snprintf(rate, sizeof(rate),
-               PL_("\n(%d turn/advance)", "\n(%d turns/advance)",
-                   turns_to_advance), turns_to_advance);
-  }
-  sz_strlcat(text, rate);
+  sz_strlcat(text, science_dialog_text());
   SetWindowText(GetDlgItem(science_dlg,ID_SCIENCE_TOP),text);
   ListBox_ResetContent(GetDlgItem(science_dlg,ID_SCIENCE_LIST));
   for (i=A_FIRST;i<game.num_tech_types;i++)
Index: client/gui-xaw/repodlgs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/repodlgs.c,v
retrieving revision 1.52
diff -u -r1.52 repodlgs.c
--- client/gui-xaw/repodlgs.c   2003/09/15 19:40:53     1.52
+++ client/gui-xaw/repodlgs.c   2003/09/16 15:23:26
@@ -41,6 +41,7 @@
 #include "support.h"
 
 #include "cityrep.h"
+#include "climisc.h"
 #include "clinet.h"
 #include "dialogs.h"
 #include "gui_main.h"
@@ -144,11 +145,11 @@
 /****************************************************************
 ...
 ****************************************************************/
-static char *get_report_title_plus(char *report_name, char *additional)
+static char *get_report_title_plus(char *report_name, const char *additional)
 {
   char buf[512];
   
-  my_snprintf(buf, sizeof(buf), _("%s\n%s of the %s\n%s %s: %s%s"),
+  my_snprintf(buf, sizeof(buf), _("%s\n%s of the %s\n%s %s: %s\n%s"),
              report_name,
              get_government_name(game.player_ptr->government),
              get_nation_name_plural(game.player_ptr->nation),
@@ -240,7 +241,6 @@
   tech_list_names_ptrs[j]=0;
   qsort(tech_list_names_ptrs, j, sizeof(char *), compare_strings_ptrs);
   num_list = j;
-  /* printf("science list num: %d\n", num_list); */
   
   science_dialog_shell =
     I_T(XtVaCreatePopupShell("sciencepopup", 
@@ -483,19 +483,9 @@
     static char *tech_list_names_ptrs[A_LAST+1];
     int j, flag;
     size_t i;
-    char rate_text[128];
     char *report_title;
-    int turns_to_advance;
     
-    turns_to_advance = tech_turns_to_advance(game.player_ptr);
-    if (turns_to_advance == FC_INFINITY) {
-      my_snprintf(rate_text, sizeof(rate_text), _("\n(no research)"));
-    } else {
-      my_snprintf(rate_text, sizeof(rate_text),
-                 PL_("\n(%d turn/advance)", "\n(%d turns/advance)",
-                     turns_to_advance), turns_to_advance);
-    }
-    report_title=get_report_title_plus(_("Science"), rate_text);
+    report_title = get_report_title_plus(_("Science"), science_dialog_text());
     xaw_set_label(science_label, report_title);
     free(report_title);
 
Index: common/diptreaty.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/diptreaty.h,v
retrieving revision 1.13
diff -u -r1.13 diptreaty.h
--- common/diptreaty.h  2003/09/09 15:49:06     1.13
+++ common/diptreaty.h  2003/09/16 15:23:26
@@ -18,10 +18,11 @@
 enum clause_type { CLAUSE_ADVANCE, CLAUSE_GOLD, CLAUSE_MAP,
                   CLAUSE_SEAMAP, CLAUSE_CITY, 
                   CLAUSE_CEASEFIRE, CLAUSE_PEACE, CLAUSE_ALLIANCE,
-                  CLAUSE_VISION, CLAUSE_LAST };
+                  CLAUSE_VISION, CLAUSE_TEAM, CLAUSE_LAST };
 
-#define is_pact_clause(x) \
-  ((x == CLAUSE_CEASEFIRE) || (x == CLAUSE_PEACE) || (x == CLAUSE_ALLIANCE))
+#define is_pact_clause(x)                                                   \
+  ((x == CLAUSE_CEASEFIRE) || (x == CLAUSE_PEACE) || (x == CLAUSE_ALLIANCE) \
+   || (x == CLAUSE_TEAM))
 
 /* For when we need to iterate over treaties */
 struct Clause;
Index: common/packets.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.c,v
retrieving revision 1.256
diff -u -r1.256 packets.c
--- common/packets.c    2003/09/15 19:40:53     1.256
+++ common/packets.c    2003/09/16 15:23:26
@@ -902,6 +902,8 @@
 
   dio_put_uint32(&dout, pinfo->bulbs_researched);
   dio_put_uint32(&dout, pinfo->techs_researched);
+  dio_put_uint32(&dout, pinfo->bulbs_last_turn);
+  dio_put_uint32(&dout, pinfo->bulbs_last_turn_techpool);
   dio_put_uint8(&dout, pinfo->researching);
 
   dio_put_bit_string(&dout, (char *) pinfo->inventions);
@@ -960,6 +962,8 @@
 
   dio_get_uint32(&din, &pinfo->bulbs_researched);
   dio_get_uint32(&din, &pinfo->techs_researched);
+  dio_get_uint32(&din, &pinfo->bulbs_last_turn);
+  dio_get_uint32(&din, &pinfo->bulbs_last_turn_techpool);
   dio_get_uint8(&din, &pinfo->researching);
   dio_get_bit_string(&din, (char *) pinfo->inventions,
                     sizeof(pinfo->inventions));
Index: common/packets.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.h,v
retrieving revision 1.153
diff -u -r1.153 packets.h
--- common/packets.h    2003/09/15 19:40:53     1.153
+++ common/packets.h    2003/09/16 15:23:26
@@ -521,6 +521,8 @@
   int gold, tax, science, luxury;
   int bulbs_researched;
   int techs_researched;
+  int bulbs_last_turn;
+  int bulbs_last_turn_techpool;
   int researching;
   int future_tech;
   int tech_goal;
Index: common/player.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.c,v
retrieving revision 1.125
diff -u -r1.125 player.c
--- common/player.c     2003/08/14 19:07:01     1.125
+++ common/player.c     2003/09/16 15:23:26
@@ -125,6 +125,8 @@
   plr->economic.science=PLAYER_DEFAULT_SCIENCE_RATE;
   plr->economic.luxury=PLAYER_DEFAULT_LUXURY_RATE;
   plr->research.changed_from = -1;
+  plr->research.bulbs_last_turn = 0;
+  plr->research.bulbs_last_turn_techpool = 0;
   player_limit_to_government_rates(plr);
   spaceship_init(&plr->spaceship);
 
@@ -568,7 +570,8 @@
     N_("?diplomatic_state:Cease-fire"),
     N_("?diplomatic_state:Peace"),
     N_("?diplomatic_state:Alliance"),
-    N_("?diplomatic_state:Never met")
+    N_("?diplomatic_state:Never met"),
+    N_("?diplomatic_state:Team")
   };
 
   if (type < DS_LAST) {
@@ -616,7 +619,7 @@
   if (is_barbarian(pplayer) || is_barbarian(pplayer2)) {
     return FALSE;
   }
-  return (ds == DS_ALLIANCE);
+  return (ds == DS_ALLIANCE || ds == DS_TEAM);
 }
 
 /***************************************************************
Index: common/player.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.h,v
retrieving revision 1.106
diff -u -r1.106 player.h
--- common/player.h     2003/08/19 16:33:19     1.106
+++ common/player.h     2003/09/16 15:23:26
@@ -66,6 +66,8 @@
 struct player_research {
   int bulbs_researched;   /* # bulbs reseached for the current tech */    
   int techs_researched;   /* # techs the player has researched/acquired */
+  int bulbs_last_turn;
+  int bulbs_last_turn_techpool;
   /* 
    * Invention being researched in. Valid values for researching are:
    *  - any existing tech but not A_NONE or
@@ -153,6 +155,7 @@
   DS_PEACE,
   DS_ALLIANCE,
   DS_NO_CONTACT,
+  DS_TEAM,
   DS_LAST      /* leave this last */
 };
 
Index: server/cityturn.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/cityturn.c,v
retrieving revision 1.222
diff -u -r1.222 cityturn.c
--- server/cityturn.c   2003/09/09 15:55:52     1.222
+++ server/cityturn.c   2003/09/16 15:23:27
@@ -1030,11 +1030,13 @@
 
       do_free_cost(pplayer);
       first = pplayer->research.researching;
-      found_new_tech(pplayer, pplayer->research.researching, TRUE, TRUE);
+      found_new_tech(pplayer, pplayer->research.researching, TRUE, TRUE, 
+                     A_NONE);
 
       do_free_cost(pplayer);
       second = pplayer->research.researching;
-      found_new_tech(pplayer, pplayer->research.researching, TRUE, TRUE);
+      found_new_tech(pplayer, pplayer->research.researching, TRUE, TRUE,
+                     A_NONE);
 
       (void) mystrlcpy(buffer, get_tech_name(pplayer, first),
                       sizeof(buffer));
Index: server/diplhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/diplhand.c,v
retrieving revision 1.73
diff -u -r1.73 diplhand.c
--- server/diplhand.c   2003/08/08 22:11:42     1.73
+++ server/diplhand.c   2003/09/16 15:23:27
@@ -293,6 +293,13 @@
            goto cleanup;
          }
          break;
+       case CLAUSE_TEAM:
+          /* Limitation: Only for teams */
+          if (other->team == TEAM_NONE || other->team != pplayer->team) {
+            freelog(LOG_ERROR, "Attempted to make team in-game!");
+            goto cleanup;
+          }
+          break;
        case CLAUSE_ALLIANCE:
           /* We need to recheck this way since things might have
            * changed. */
@@ -368,7 +375,7 @@
 
        do_dipl_cost(pdest);
 
-       found_new_tech(pdest, pclause->value, FALSE, TRUE);
+       found_new_tech(pdest, pclause->value, FALSE, TRUE, A_NONE);
        break;
       case CLAUSE_GOLD:
        notify_player(pdest, _("Game: You get %d gold."), pclause->value);
@@ -445,6 +452,47 @@
        check_city_workers(plr0);
        check_city_workers(plr1);
        break;
+      case CLAUSE_TEAM:
+        notify_player_ex(pgiver, -1, -1, E_TREATY_ALLIANCE,
+                         _("Game: You start a research pool with %s."),
+                         pdest->name);
+        notify_player_ex(pdest, -1, -1, E_TREATY_ALLIANCE,
+                         _("Game: You start a research pool with %s."),
+                         pgiver->name);
+        /* We must share and average research */
+        {
+          int average = (plr0->research.bulbs_researched
+                         + plr1->research.bulbs_researched) / 2;
+          int average2 = (plr0->research.bulbs_researched_before
+                          + plr1->research.bulbs_researched_before) / 2;
+          int tech;
+ 
+          for (tech = 0; tech < A_LAST; tech++) {
+            if (!tech_exists(tech)) {
+              continue;
+            }
+            if (get_invention(plr0, tech) != TECH_KNOWN
+                && get_invention(plr1, tech) == TECH_KNOWN) {
+              found_new_tech(plr0, tech, FALSE, TRUE, A_NONE);
+            }
+            if (get_invention(plr1, tech) != TECH_KNOWN
+                && get_invention(plr0, tech) == TECH_KNOWN) {
+              found_new_tech(plr1, tech, FALSE, TRUE, A_NONE);
+            }
+          }
+          plr0->research.bulbs_researched = average;
+          plr1->research.bulbs_researched = average;
+          plr1->research.researching = plr0->research.researching;
+          plr1->research.changed_from = plr0->research.changed_from;
+          plr0->research.bulbs_researched_before = average2;
+          plr1->research.bulbs_researched_before = average2;
+          plr1->ai.tech_goal = plr0->ai.tech_goal;
+        }
+        pgiver->diplstates[pdest->player_no].type = DS_TEAM;
+        pdest->diplstates[pgiver->player_no].type = DS_TEAM;
+        check_city_workers(plr0);
+        check_city_workers(plr1);
+        break;
       case CLAUSE_VISION:
        give_shared_vision(pgiver, pdest);
        notify_player_ex(pgiver, -1, -1, E_TREATY_SHARED_VISION,
Index: server/diplomats.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/diplomats.c,v
retrieving revision 1.42
diff -u -r1.42 diplomats.c
--- server/diplomats.c  2003/09/09 20:10:28     1.42
+++ server/diplomats.c  2003/09/16 15:23:27
@@ -656,7 +656,7 @@
 
     /* Do it. */
     do_conquer_cost (pplayer);
-    found_new_tech (pplayer, target, FALSE, TRUE);
+    found_new_tech (pplayer, target, FALSE, TRUE, A_NONE);
     /* Report it. */
     notify_player_ex(pplayer, pcity->x, pcity->y, E_MY_DIPLOMAT_THEFT,
                     _("Game: Your %s stole %s from %s."),
Index: server/plrhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.c,v
retrieving revision 1.293
diff -u -r1.293 plrhand.c
--- server/plrhand.c    2003/09/15 16:51:07     1.293
+++ server/plrhand.c    2003/09/16 15:23:27
@@ -148,7 +148,7 @@
                           advances[i].name);
 
          do_free_cost(pplayer);
-         found_new_tech(pplayer, i, FALSE, FALSE);
+         found_new_tech(pplayer, i, FALSE, FALSE, A_NONE);
          break;
        }
       } tech_type_iterate_end;
@@ -254,12 +254,13 @@
 }
 
 /**************************************************************************
-Player has a new technology (from somewhere)
-was_discovery is passed on to upgrade_city_rails
-Logging & notification is not done here as it depends on how the tech came.
+  Player has a new technology (from somewhere). was_discovery is passed 
+  on to upgrade_city_rails. Logging & notification is not done here as 
+  it depends on how the tech came. If next_tech is other than A_NONE, this 
+  is the next tech to research.
 **************************************************************************/
 void found_new_tech(struct player *plr, int tech_found, bool was_discovery,
-                   bool saving_bulbs)
+                   bool saving_bulbs, int next_tech)
 {
   bool bonus_tech_hack = FALSE;
   bool was_first = FALSE;
@@ -332,7 +333,7 @@
     plr->ai.tech_goal = A_UNSET;
   }
 
-  if (tech_found==plr->research.researching) {
+  if (tech_found == plr->research.researching && next_tech == A_NONE) {
     /* need to pick new tech to research */
 
     int saved_bulbs = plr->research.bulbs_researched;
@@ -369,6 +370,12 @@
     if (saving_bulbs) {
       plr->research.bulbs_researched = saved_bulbs;
     }
+  } else if (tech_found == plr->research.researching && next_tech > A_NONE) {
+    /* Next target already determined. We always save bulbs. */
+    plr->research.researching = next_tech;
+    if (plr->research.bulbs_researched > 0) {
+      plr->research.bulbs_researched = 0;
+    }
   }
 
   if (bonus_tech_hack) {
@@ -422,6 +429,26 @@
       } players_iterate_end;
     }
   }
+
+  /* Update Team */
+  if (next_tech > A_NONE) {
+    /* Avoid unnecessary recursion. */
+    return;
+  }
+  players_iterate(aplayer) {
+    if (plr != aplayer
+        && plr->diplstates[aplayer->player_no].type == DS_TEAM
+        && aplayer->is_alive
+        && get_invention(aplayer, tech_found) != TECH_KNOWN) {
+      notify_player_ex(aplayer, -1, -1, E_TECH_LEARNED,
+                       _("Game: Learned %s in cooperation with %s."
+                         "Scientists choose to research %s."),
+                       advances[tech_found].name, plr->name,
+                       get_tech_name(plr, plr->research.researching));
+      found_new_tech(aplayer, tech_found, was_discovery, saving_bulbs,
+                     plr->research.researching);
+    }
+  } players_iterate_end;
 }
 
 /**************************************************************************
@@ -461,7 +488,7 @@
   }
 
   /* do all the updates needed after finding new tech */
-  found_new_tech(plr, plr->research.researching, TRUE, FALSE);
+  found_new_tech(plr, plr->research.researching, TRUE, FALSE, A_NONE);
 }
 
 /**************************************************************************
@@ -471,7 +498,18 @@
 {
   int excessive_bulbs;
 
-  plr->research.bulbs_researched += bulbs;
+  players_iterate(pplayer) {
+    if (pplayer == plr) {
+      pplayer->research.bulbs_researched += bulbs;
+      pplayer->research.bulbs_last_turn += bulbs;
+      pplayer->research.bulbs_last_turn_techpool += bulbs;
+    } else if (pplayer->diplstates[plr->player_no].type == DS_TEAM
+               && pplayer->is_alive) {
+      /* Share with union partner(s). We'll get in return later. */
+      pplayer->research.bulbs_researched += bulbs;
+      pplayer->research.bulbs_last_turn_techpool += bulbs;
+    }
+  } players_iterate_end;
   
   excessive_bulbs =
       (plr->research.bulbs_researched - total_bulbs_required(plr));
@@ -514,7 +552,6 @@
   return FALSE;
 }
 
-
 /**************************************************************************
 ...
 **************************************************************************/
@@ -692,7 +729,7 @@
                   get_nation_name_plural(target->nation));
 
   do_conquer_cost(pplayer);
-  found_new_tech(pplayer, stolen_tech, FALSE, TRUE);
+  found_new_tech(pplayer, stolen_tech, FALSE, TRUE, A_NONE);
 }
 
 /**************************************************************************
@@ -748,6 +785,16 @@
 {
   choose_tech(pplayer, preq->tech);
   send_player_info(pplayer, pplayer);
+
+  /* Notify Team members */
+  players_iterate(aplayer) {
+    if (pplayer != aplayer
+       && aplayer->research.researching != preq->tech
+       && pplayer->diplstates[aplayer->player_no].type == DS_TEAM
+       && aplayer->is_alive) {
+      handle_player_research(aplayer, preq);
+    }
+  } players_iterate_end;
 }
 
 /**************************************************************************
@@ -758,6 +805,16 @@
 {
   choose_tech_goal(pplayer, preq->tech);
   send_player_info(pplayer, pplayer);
+
+  /* Notify Team members */
+  players_iterate(aplayer) {
+    if (pplayer != aplayer
+        && pplayer->diplstates[aplayer->player_no].type == DS_TEAM
+        && aplayer->is_alive
+        && aplayer->ai.tech_goal != preq->tech) {
+      handle_player_tech_goal(aplayer, preq);
+    }
+  } players_iterate_end;
 }
 
 /**************************************************************************
@@ -893,8 +950,10 @@
     return;
   }
 
-  /* can't break a pact with a team member */
-  if (pplayer->team != TEAM_NONE && pplayer->team == pplayer2->team) {
+  /* Can't break alliance with a team member, but can reduce a team
+   * research to an alliance for stand-alone research. */
+  if (pplayer->team != TEAM_NONE && pplayer->team == pplayer2->team
+      && old_type != DS_TEAM) {
     return;
   }
 
@@ -932,6 +991,10 @@
     new_type = DS_PEACE;
     reppenalty = GAME_MAX_REPUTATION/4;
     break;
+  case DS_TEAM:
+    new_type = DS_ALLIANCE;
+    reppenalty = 0;
+    break;
   default:
     freelog(LOG_VERBOSE, "non-pact diplstate in handle_player_cancel_pact");
     return;
@@ -1265,6 +1328,8 @@
     packet->luxury          = plr->economic.luxury;
     packet->bulbs_researched= plr->research.bulbs_researched;
     packet->techs_researched= plr->research.techs_researched;
+    packet->bulbs_last_turn = plr->research.bulbs_last_turn;
+    packet->bulbs_last_turn_techpool = plr->research.bulbs_last_turn_techpool;
     packet->researching     = plr->research.researching;
     packet->future_tech     = plr->future_tech;
     if (plr->revolution != 0) {
@@ -1292,6 +1357,8 @@
     packet->luxury          = 0;
     packet->bulbs_researched= 0;
     packet->techs_researched= 0;
+    packet->bulbs_last_turn = 0;
+    packet->bulbs_last_turn_techpool = 0;
     packet->researching     = A_NOINFO;
     packet->future_tech     = 0;
     packet->revolution      = 0;
@@ -1330,7 +1397,8 @@
    * A_NONE. */
   packet->inventions[A_NONE] = plr->research.inventions[A_NONE].state + '0';
 
-  if (info_level >= INFO_FULL) {
+  if (info_level >= INFO_FULL
+      || plr->diplstates[receiver->player_no].type == DS_TEAM) {
     packet->tech_goal       = plr->ai.tech_goal;
   } else {
     packet->tech_goal       = A_UNSET;
@@ -1439,6 +1507,8 @@
       || is_barbarian(pplayer1) || is_barbarian(pplayer2)) {
     return;
   }
+  pplayer1->diplstates[player2].contact_turns_left = game.contactturns;
+  pplayer2->diplstates[player1].contact_turns_left = game.contactturns;
 
   pplayer1->diplstates[player2].contact_turns_left = game.contactturns;
   pplayer2->diplstates[player1].contact_turns_left = game.contactturns;
@@ -1670,6 +1740,8 @@
   cplayer->research.bulbs_researched = 0;
   cplayer->research.techs_researched = pplayer->research.techs_researched;
   cplayer->research.researching = pplayer->research.researching;
+  cplayer->research.bulbs_last_turn = 0;
+  cplayer->research.bulbs_last_turn_techpool = 0;
 
   tech_type_iterate(i) {
     cplayer->research.inventions[i] = pplayer->research.inventions[i];
Index: server/plrhand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.h,v
retrieving revision 1.56
diff -u -r1.56 plrhand.h
--- server/plrhand.h    2003/08/09 15:34:19     1.56
+++ server/plrhand.h    2003/09/16 15:23:27
@@ -69,8 +69,8 @@
 void handle_player_attribute_chunk(struct player *pplayer,
                                   struct packet_attribute_chunk *chunk);
 void handle_player_attribute_block(struct player *pplayer);
-void found_new_tech(struct player *plr, int tech_found, bool was_discovery, 
-                   bool saving_bulbs);
+void found_new_tech(struct player *plr, int tech_found, bool was_discovery,
+                    bool saving_bulbs, int next_tech);
 void found_new_future_tech(struct player *pplayer);
 void update_tech(struct player *plr, int bulbs);
 void init_tech(struct player *plr, int tech);
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.135
diff -u -r1.135 savegame.c
--- server/savegame.c   2003/09/09 15:49:07     1.135
+++ server/savegame.c   2003/09/16 15:23:27
@@ -675,6 +675,8 @@
                                             "player%d.researchpoints", plrno);
   plr->research.researching=secfile_lookup_int(file, 
                                             "player%d.researching", plrno);
+  plr->research.bulbs_last_turn = 0;
+  plr->research.bulbs_last_turn_techpool = 0;
   if (plr->research.researching == A_NONE
       || !tech_exists(plr->research.researching)) {
     /* The value of A_FUTURE could change in the future, since it
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.136
diff -u -r1.136 srv_main.c
--- server/srv_main.c   2003/09/15 19:40:53     1.136
+++ server/srv_main.c   2003/09/16 15:23:27
@@ -494,6 +494,11 @@
     }
   } players_iterate_end;
 
+  players_iterate(pplayer) {
+    pplayer->research.bulbs_last_turn = 0;
+    pplayer->research.bulbs_last_turn_techpool = 0;
+  } players_iterate_end;
+
   /* Refresh cities */
   shuffled_players_iterate(pplayer) {
     great_library(pplayer);
@@ -1760,7 +1765,7 @@
      players_iterate(pdest) {
       if (pplayer->team == pdest->team && pplayer->team != TEAM_NONE
           && pplayer->player_no != pdest->player_no) {
-        pplayer->diplstates[pdest->player_no].type = DS_ALLIANCE;
+        pplayer->diplstates[pdest->player_no].type = DS_TEAM;
         give_shared_vision(pplayer, pdest);
         pplayer->embassy |= (1 << pdest->player_no);
       }
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.249
diff -u -r1.249 unittools.c
--- server/unittools.c  2003/09/10 16:50:18     1.249
+++ server/unittools.c  2003/09/16 15:23:27
@@ -2218,7 +2218,7 @@
 
   do_free_cost(pplayer);
   if (!is_future_tech(new_tech)) {
-    found_new_tech(pplayer, new_tech, FALSE, TRUE);
+    found_new_tech(pplayer, new_tech, FALSE, TRUE, A_NONE);
   } else {
     found_new_future_tech(pplayer);
   }

[Prev in Thread] Current Thread [Next in Thread]