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

[Freeciv-Dev] Re: 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] Re: Team research (PR#4213)
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Sun, 21 Sep 2003 06:13:51 -0700
Reply-to: rt@xxxxxxxxxxxxxx

On Wed, 17 Sep 2003, Genevieve Gracian wrote:
> The bulbs/turn are related to what you obtained last turn, it's less
> useful imho than having a "real time" update of this value like
> turns/tech which is updated when you change the trade rates.

Changed. I expanded short_city packet with one field for this. I hope Greg
or Jason can take a look at it to ensure that we don't leak any unwanted
info here; I am not very knowledgable about dumb_city.

> Also, the fact that sharing research is a clause in a treaty is fine,
> but I think it should have an implementation similar to shared vision,
> not to diplomatic state. Perhaps even, a generic entry for "sharing" in
> treaties can be done, so that it can be considered in the future to
> share money output and maybe other items.

Since we restrict this to teams, I do not see the point in making it a
'shared vision' like option. It is more easily hidden when it is in the
pact menu. For non-team games, the menu option for team research is simply
not added.

  - Per

Index: ai/advdiplomacy.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/advdiplomacy.c,v
retrieving revision 1.5
diff -u -r1.5 advdiplomacy.c
--- ai/advdiplomacy.c   2003/09/16 15:12:39     1.5
+++ ai/advdiplomacy.c   2003/09/21 13:54:25
@@ -201,6 +201,10 @@
     } players_iterate_end;
   break;
 
+  case CLAUSE_TEAM:
+    worth = 1;
+    break;
+
   case CLAUSE_ALLIANCE:
   case CLAUSE_PEACE:
   case CLAUSE_CEASEFIRE:
@@ -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: ai/aitech.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitech.c,v
retrieving revision 1.40
diff -u -r1.40 aitech.c
--- ai/aitech.c 2003/07/21 01:43:51     1.40
+++ ai/aitech.c 2003/09/21 13:54:25
@@ -236,12 +236,21 @@
 }
 
 /**************************************************************************
-  ...
+  Key AI research function. Disable if we are in a team with human team
+  mates in a research pool.
 **************************************************************************/
 void ai_manage_tech(struct player *pplayer)
 {
   struct ai_choice choice, gol;
   int penalty;
+
+  players_iterate(aplayer) {
+    const struct player_diplstate *ds = pplayer_get_diplstate(pplayer, 
aplayer);
+
+    if (ds->type == DS_TEAM) {
+      return;
+    }
+  } players_iterate_end;
 
   penalty = (pplayer->got_tech ? 0 : pplayer->research.bulbs_researched);
 
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/21 13:54:25
@@ -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,58 @@
                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];
+  struct player *plr = game.player_ptr;
+  int ours = 0, theirs = 0;
+
+  /* Sum up science */
+  players_iterate(pplayer) {
+    enum diplstate_type ds = pplayer_get_diplstate(plr, pplayer)->type;
+
+    if (plr == pplayer) {
+      city_list_iterate(pplayer->cities, pcity) {
+        ours += pcity->science_total;
+      } city_list_iterate_end;
+    } else if (ds == DS_TEAM) {
+      city_list_iterate(pplayer->cities, pcity) {
+        theirs += pcity->science_total;
+      } city_list_iterate_end;
+    }
+  } players_iterate_end;
+
+  if (ours == 0 && theirs == 0) {
+    my_snprintf(text, sizeof(text), _("Progress: no research"));
+    return text;
+  }
+  if (ours < 0 || theirs < 0) {
+    die("Negative science in science_dialog_text");
+  }
+  turns_to_advance = (total_bulbs_required(plr) + ours + theirs - 1)
+                     / (ours + theirs);
+  if (theirs == 0) {
+    /* 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, ours);
+  } else {
+    /* Techpool version */
+    my_snprintf(text, sizeof(text),
+                PL_("Progress: %d turn/advance (%d pts/turn, "
+                    "%d pts/turn from team)",
+                    "Progress: %d turns/advance (%d pts/turn, "
+                    "%d pts/turn from team)",
+                    turns_to_advance),
+                turns_to_advance, ours, theirs);
+  }
+  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/21 13:54:25
@@ -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/21 13:54:25
@@ -628,6 +628,7 @@
   
   pcity->size=packet->size;
   pcity->tile_trade = packet->tile_trade;
+  pcity->science_total = packet->science_total;
 
   /* We can't actually see the internals of the city, but the server tells
    * us this much. */
@@ -683,7 +684,6 @@
     pcity->corruption         = 0;
     pcity->luxury_total       = 0;
     pcity->tax_total          = 0;
-    pcity->science_total      = 0;
     pcity->food_stock         = 0;
     pcity->shield_stock       = 0;
     pcity->pollution          = 0;
@@ -1445,10 +1445,10 @@
                || 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;
+
   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/21 13:54:25
@@ -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);
+    gtk_signal_connect(GTK_OBJECT(item), "activate",
+                     GTK_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/21 13:54:25
@@ -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/21 13:54:25
@@ -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/21 13:54: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/21 13:54: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/21 13:54: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/21 13:54: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/21 13:54: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/capstr.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v
retrieving revision 1.143
diff -u -r1.143 capstr.c
--- common/capstr.c     2003/09/09 20:10:28     1.143
+++ common/capstr.c     2003/09/21 13:54:26
@@ -80,7 +80,7 @@
                    "+no_nation_selected +diplomacy +no_extra_tiles " \
                    "+diplomacy2 +citizens_style +root_tech auth " \
                    "+nat_ulimit +retake +goto_pack borders dip " \
-                   "+packet_short_unit"
+                   "+packet_short_unit +teamres"
 
 /* "+1.14.0" is protocol for 1.14.0 release.
  *
@@ -149,6 +149,8 @@
  *
  * "packet_short_unit" is packet sent instead of full packet_unit_info to
  * enemies, so that not all info about the unit is sent.
+ * 
+ * "teamres" means team research. Now teams by default research together.
  */
 
 void init_our_capability(void)
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/21 13:54: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/21 13:54:26
@@ -1512,6 +1512,7 @@
                        | COND_SET_BIT(req->unhappy, 5)));
 
   dio_put_uint16(&dout, req->tile_trade);
+  dio_put_uint16(&dout, req->science_total);
 
   SEND_PACKET_END;
 }
@@ -1542,6 +1543,7 @@
   packet->unhappy = TEST_BIT(i, 5);
 
   dio_get_uint16(&din, &packet->tile_trade);
+  dio_get_uint16(&din, &packet->science_total);
 
   RECEIVE_PACKET_END(packet);
 }
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/21 13:54:26
@@ -415,6 +415,7 @@
   bool walls;                  /* boolean */
   bool occupied;               /* boolean */
   int tile_trade;              /* same as in packet_city_info */
+  int science_total;           /* same as in packet_city_info */
 };
 
 
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/21 13:54:26
@@ -568,7 +568,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 +617,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/21 13:54:26
@@ -153,6 +153,7 @@
   DS_PEACE,
   DS_ALLIANCE,
   DS_NO_CONTACT,
+  DS_TEAM,
   DS_LAST      /* leave this last */
 };
 
Index: common/tech.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/tech.c,v
retrieving revision 1.68
diff -u -r1.68 tech.c
--- common/tech.c       2003/08/11 02:24:03     1.68
+++ common/tech.c       2003/09/21 13:54:26
@@ -327,27 +327,6 @@
 }
 
 /**************************************************************************
- Returns number of turns to advance (assuming current state of
- civilization).
-**************************************************************************/
-int tech_turns_to_advance(struct player *pplayer)
-{
-  /* The number of bulbs the civilization produces every turn. */
-  int current_output = 0;
-
-  city_list_iterate(pplayer->cities, pcity) {
-    current_output += pcity->science_total;
-  } city_list_iterate_end;
-
-  if (current_output <= 0) {
-    return FC_INFINITY;
-  }
-
-  return ((total_bulbs_required(pplayer) + current_output - 1)
-         / current_output);
-}
-
-/**************************************************************************
   Returns the number of bulbs which are required to finished the
   currently researched tech denoted by
   pplayer->research.researching. This is _NOT_ the number of bulbs
Index: common/tech.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/tech.h,v
retrieving revision 1.42
diff -u -r1.42 tech.h
--- common/tech.h       2003/08/11 02:24:03     1.42
+++ common/tech.h       2003/09/21 13:54:26
@@ -121,8 +121,6 @@
 enum tech_flag_id tech_flag_from_str(const char *s);
 Tech_Type_id find_tech_by_flag(int index, enum tech_flag_id flag);
 
-int tech_turns_to_advance(struct player *pplayer);
-
 int total_bulbs_required(struct player *pplayer);
 int base_total_bulbs_required(struct player *pplayer,Tech_Type_id tech);
 bool techs_have_fixed_costs(void);
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.233
diff -u -r1.233 citytools.c
--- server/citytools.c  2003/09/20 19:24:54     1.233
+++ server/citytools.c  2003/09/21 13:54:27
@@ -1354,6 +1354,12 @@
   } else {
     packet->tile_trade = 0;
   }
+  if (pcity && pplayer->team != TEAM_NONE
+      && pplayer->team == city_owner(pcity)->team) {
+    packet->science_total = pcity->science_total; /* Know science of team */
+  } else {
+    packet->science_total = 0;
+  }
 }
 
 /**************************************************************************
@@ -1676,6 +1682,7 @@
       && pdcity->occupied == occupied
       && pdcity->happy == happy
       && pdcity->unhappy == unhappy
+      && pdcity->science_total == pcity->science_total
       && pdcity->owner == pcity->owner) {
     return FALSE;
   }
@@ -1696,6 +1703,7 @@
   pdcity->happy = happy;
   pdcity->unhappy = unhappy;
   pdcity->owner = pcity->owner;
+  pdcity->science_total = pcity->science_total;
 
   return TRUE;
 }
Index: server/cityturn.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/cityturn.c,v
retrieving revision 1.223
diff -u -r1.223 cityturn.c
--- server/cityturn.c   2003/09/20 19:24:54     1.223
+++ server/cityturn.c   2003/09/21 13:54:27
@@ -980,11 +980,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/21 13:54: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/21 13:54: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/maphand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.h,v
retrieving revision 1.38
diff -u -r1.38 maphand.h
--- server/maphand.h    2003/08/01 19:58:47     1.38
+++ server/maphand.h    2003/09/21 13:54:27
@@ -31,6 +31,7 @@
   char name[MAX_LEN_NAME];
   unsigned short size;
   unsigned char owner;
+  unsigned short science_total;
 };
 
 struct player_tile {
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/21 13:54: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,15 @@
 {
   int excessive_bulbs;
 
-  plr->research.bulbs_researched += bulbs;
+  players_iterate(pplayer) {
+    if (pplayer == plr) {
+      pplayer->research.bulbs_researched += 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;
+    }
+  } players_iterate_end;
   
   excessive_bulbs =
       (plr->research.bulbs_researched - total_bulbs_required(plr));
@@ -514,7 +549,6 @@
   return FALSE;
 }
 
-
 /**************************************************************************
 ...
 **************************************************************************/
@@ -692,7 +726,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 +782,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 +802,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 +947,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 +988,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;
@@ -1330,7 +1390,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 +1500,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;
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/21 13:54: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.136
diff -u -r1.136 savegame.c
--- server/savegame.c   2003/09/19 22:27:18     1.136
+++ server/savegame.c   2003/09/21 13:54:27
@@ -1237,6 +1237,7 @@
        pdcity->unhappy = secfile_lookup_bool_default(file, FALSE,
                                        "player%d.dc%d.unhappy", plrno, j);
        pdcity->owner = secfile_lookup_int(file, "player%d.dc%d.owner", plrno, 
j);
+        pdcity->science_total = 0;
        map_get_player_tile(x, y, plr)->city = pdcity;
        alloc_id(pdcity->id);
       }
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.138
diff -u -r1.138 srv_main.c
--- server/srv_main.c   2003/09/20 19:24:54     1.138
+++ server/srv_main.c   2003/09/21 13:54:27
@@ -1759,7 +1759,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.253
diff -u -r1.253 unittools.c
--- server/unittools.c  2003/09/21 09:06:43     1.253
+++ server/unittools.c  2003/09/21 13:54:27
@@ -2236,7 +2236,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]