Complete.Org: Mailing Lists: Archives: freeciv-dev: October 2001:
[Freeciv-Dev] init_techs integrated patch (PR#999)
Home

[Freeciv-Dev] init_techs integrated patch (PR#999)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Cc: bugs@xxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] init_techs integrated patch (PR#999)
From: Arien Malec <arien_malec@xxxxxxxxx>
Date: Mon, 8 Oct 2001 22:22:25 -0700 (PDT)

Attached is a merged patch incorporating global and nation-specific init techs.
This includes my work (global) and the work of the FreecivAC team (nation
specific). Some work was done to harmonize naming (e.g., the FreecivAC patch
had a ruleset variable named free_tech; this patch calls it init_techs) and use
similar coding and data coventions (e.g., using A_LAST terminated tech arrays).

Initial techs are useful for creating scenarios (e.g., modern warfare) and for
testing. Nation-specific initial techs, combined with a multiply rooted tech
tree, can be used to create special capabilities for specific nations.

Arien

__________________________________________________
Do You Yahoo!?
NEW from Yahoo! GeoCities - quick and easy web site hosting, just $8.95/month.
http://geocities.yahoo.com/ps/info1
Index: common/capstr.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v
retrieving revision 1.88
diff -u -r1.88 capstr.c
--- common/capstr.c     2001/10/06 21:02:01     1.88
+++ common/capstr.c     2001/10/09 05:14:03
@@ -71,7 +71,7 @@
  */
 
 #define CAPABILITY "+1.11.6 conn_info pop_cost turn attributes new_bonus_tech"\
-" fund_added processing_packets angrycitizen tile_trade"
+" fund_added processing_packets angrycitizen tile_trade init_techs"
   
 /* "+1.11.6" is protocol for 1.11.6 beta release.
   
@@ -100,6 +100,9 @@
    a city can become unhappy.
    
    "tile_trade" sends the tile_trade field from struct city.
+
+   "init_techs" allows global and nation specific initial techs to be
+   specified in rulesets.
 */
 
 void init_our_capability(void)
Index: common/game.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.h,v
retrieving revision 1.87
diff -u -r1.87 game.h
--- common/game.h       2001/09/16 12:43:25     1.87
+++ common/game.h       2001/10/09 05:14:03
@@ -141,7 +141,7 @@
 
   int watchtower_extra_vision;
   int watchtower_vision;
-
+  
   struct {
     char techs[MAX_LEN_NAME];
     char units[MAX_LEN_NAME];
@@ -182,6 +182,8 @@
     int nuke_contamination;
     int granary_food_ini;
     int granary_food_inc;
+    int *init_techs; /* Advances to assign to all players at game
+                       start. A_LAST terminated.*/
   } rgame;
 
   char demography[MAX_LEN_DEMOGRAPHY];
Index: common/nation.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/nation.h,v
retrieving revision 1.5
diff -u -r1.5 nation.h
--- common/nation.h     2000/03/04 03:55:27     1.5
+++ common/nation.h     2001/10/09 05:14:03
@@ -16,6 +16,7 @@
 #include "shared.h"            /* MAX_LEN_NAME */
 
 #define MAX_NUM_TECH_GOALS 10
+#define MAX_NUM_INIT_TECHS 8
 #define MAX_NUM_NATIONS  63
 #define MAX_NUM_LEADERS  16
 
@@ -42,6 +43,9 @@
   /* untranslated copies: */
   char name_orig[MAX_LEN_NAME];
   char name_plural_orig[MAX_LEN_NAME];
+
+  /* Init techs */
+  int     init_techs[MAX_NUM_INIT_TECHS + 1]; /* A_LAST terminated */
 
   /* AI hints */
   int attack;               /* c 0 = optimize for food, 2 =  optimize for prod 
 */
Index: common/packets.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.c,v
retrieving revision 1.164
diff -u -r1.164 packets.c
--- common/packets.c    2001/10/06 21:02:01     1.164
+++ common/packets.c    2001/10/09 05:14:05
@@ -3643,7 +3643,9 @@
     cptr=put_uint8(cptr, packet->leader_sex[i]);
   }
   cptr=put_uint8(cptr, packet->city_style);
-
+  if (has_capability("init_techs", pc->capability)) {
+    cptr=put_tech_list(cptr, packet->init_techs);
+  }
   put_uint16(buffer, cptr-buffer);
 
   return send_packet_data(pc, buffer, cptr-buffer);
@@ -3674,6 +3676,9 @@
     iget_uint8(&iter, &packet->leader_sex[i]);
   }
   iget_uint8(&iter, &packet->city_style);
+  if (has_capability("init_techs", pc->capability)) {
+    iget_tech_list(&iter, packet->init_techs);
+  }
 
   pack_iter_end(&iter, pc);
   remove_packet_from_buffer(pc->buffer);
@@ -3747,7 +3752,10 @@
   cptr=put_uint8(cptr, packet->nuke_contamination);
   cptr=put_uint8(cptr, packet->granary_food_ini);
   cptr=put_uint8(cptr, packet->granary_food_inc);
-
+  if (has_capability("init_techs", pc->capability)) {
+    cptr=put_tech_list(cptr, packet->init_techs);
+  }
+  
   put_uint16(buffer, cptr-buffer);
   return send_packet_data(pc, buffer, cptr-buffer);
 }
@@ -3774,6 +3782,9 @@
   iget_uint8(&iter, &packet->nuke_contamination);
   iget_uint8(&iter, &packet->granary_food_ini);
   iget_uint8(&iter, &packet->granary_food_inc);
+  if (has_capability("init_techs", pc->capability)) {
+    iget_tech_list(&iter, packet->init_techs);
+  }
 
   pack_iter_end(&iter, pc);
   remove_packet_from_buffer(pc->buffer);
Index: common/packets.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.h,v
retrieving revision 1.96
diff -u -r1.96 packets.h
--- common/packets.h    2001/10/06 21:02:02     1.96
+++ common/packets.h    2001/10/09 05:14:06
@@ -763,6 +763,7 @@
   char leader_name[MAX_NUM_LEADERS][MAX_LEN_NAME];
   int leader_sex[MAX_NUM_LEADERS];
   int city_style;
+  int init_techs[MAX_NUM_TECH_LIST];
 };
 
 struct packet_ruleset_city {
@@ -785,6 +786,7 @@
   int nuke_contamination;
   int granary_food_ini;
   int granary_food_inc;
+  int init_techs[MAX_NUM_TECH_LIST];
 };
 
 /*********************************************************
Index: data/default/game.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/game.ruleset,v
retrieving revision 1.3
diff -u -r1.3 game.ruleset
--- data/default/game.ruleset   2001/01/22 04:57:17     1.3
+++ data/default/game.ruleset   2001/10/09 05:14:06
@@ -14,6 +14,9 @@
 description="Default game rules for Freeciv"
 options="1.11.1"
 
+[options]
+init_techs = ""
+
 [civstyle]
 min_city_center_food   = 1
 min_city_center_shield = 1
Index: server/plrhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.c,v
retrieving revision 1.200
diff -u -r1.200 plrhand.c
--- server/plrhand.c    2001/10/08 12:02:08     1.200
+++ server/plrhand.c    2001/10/09 05:14:07
@@ -468,11 +468,20 @@
 void init_tech(struct player *plr, int tech)
 {
   int i;
+  struct nation_type *nation=get_nation_by_plr(plr);
+  
   for (i=0;i<game.num_tech_types;i++) 
     set_invention(plr, i, 0);
   set_invention(plr, A_NONE, TECH_KNOWN);
 
   plr->research.researchpoints=1;
+  for (i=0; game.rgame.init_techs[i] != A_LAST; i++) {
+    set_invention(plr, game.rgame.init_techs[i], TECH_KNOWN);
+  }
+  for (i=0; nation->init_techs[i] != A_LAST; i++) {
+    set_invention(plr, nation->init_techs[i], TECH_KNOWN);
+  }
+
   for (i=0;i<tech;i++) {
     choose_random_tech(plr); /* could be choose_goal_tech -- Syela */
     set_invention(plr, plr->research.researching, TECH_KNOWN);
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.80
diff -u -r1.80 ruleset.c
--- server/ruleset.c    2001/09/15 15:31:27     1.80
+++ server/ruleset.c    2001/10/09 05:14:09
@@ -1796,7 +1796,7 @@
   char *datafile_options, *bad_leader, *g;
   struct nation_type *pl;
   struct government *gov;
-  int *res, dim, val, i, j, nval;
+  int *res, dim, val, i, j, k, nval;
   char temp_name[MAX_LEN_NAME];
   char **cities, **techs, **leaders, **sec;
   const char *filename = secfile_filename(file);
@@ -1937,6 +1937,40 @@
       pl->advisors[j] = res[j];
     if(res) free(res);
 
+    /*
+     * Init techs
+     */
+    
+    techs = secfile_lookup_str_vec(file, &dim, "%s.init_techs", sec[i]);
+    if( dim > MAX_NUM_INIT_TECHS ) {
+      freelog(LOG_VERBOSE,
+              "Only %d initial techs can be given from %d"
+             "defined for nation %s",
+              MAX_NUM_INIT_TECHS, dim, pl->name_plural);
+    }
+    for(j = k = 0; j < dim; j++) {
+      if (strcmp(techs[j],"") != 0) {
+       
+       val = find_tech_by_name(techs[j]);
+       if(val == A_LAST) {
+         freelog(LOG_VERBOSE, "Didn't match init tech %d \"%s\" for %s",
+                 j, techs[j], pl->name);
+       } else if(!tech_exists(val)) {
+         freelog(LOG_VERBOSE, "Init tech %d \"%s\" for %s doesn't exist",
+                 j, techs[j], pl->name);
+       } else if(val != A_NONE) {
+         freelog(LOG_DEBUG, "%s init tech (%d) %3d %s",
+                 pl->name, j, val, techs[j]);
+         pl->init_techs[k++] = val;
+       }
+      }
+    }
+    pl->init_techs[k] = A_LAST;
+    freelog(LOG_DEBUG, "%s %d init techs", pl->name, j);
+
+    if (techs)
+      free(techs);
+
     /* AI techs */
 
     techs = secfile_lookup_str_vec(file, &dim, "%s.tech_goals", sec[i]);
@@ -2109,6 +2143,51 @@
 }
 
 /**************************************************************************
+Lookup init techs from section file
+**************************************************************************/
+static int *secfile_lookup_init_techs (struct section_file *file)
+{
+  int num_init_techs;
+  char **init_tech_names;
+  int *init_techs;
+  int i, j;
+  
+  init_tech_names = secfile_lookup_str_vec(file, &num_init_techs,
+                                          "options.init_techs");
+
+  if (num_init_techs > MAX_NUM_TECH_LIST) {
+    freelog (LOG_ERROR, "num_init_techs: %d > total number of techs",
+            num_init_techs);
+  }
+
+  init_techs = fc_malloc (sizeof(int) * num_init_techs);
+
+  for (i = j = 0; i < num_init_techs; i++) {
+    if (strcmp(init_tech_names[i],"") != 0) {
+      
+      int t = find_tech_by_name (init_tech_names[i]);
+      
+      if (t == A_LAST) {
+       freelog(LOG_VERBOSE, "Didn't match global init tech %d \"%s\"",
+               i, init_tech_names[i]);
+      } else if(!tech_exists(t)) {
+       freelog(LOG_VERBOSE, "Global init tech %d \"%s\" doesn't exist",
+               i, init_tech_names[i]);
+      } else if(t != A_NONE) {
+       freelog(LOG_DEBUG, "Global init tech (%d) %3d %s",
+               i, t, init_tech_names[i]);
+       init_techs[j++] = t;
+      }
+    }
+  }
+  init_techs[j] = A_LAST;
+
+  if (init_tech_names)
+    free (init_tech_names);
+  return init_techs;
+}
+
+/**************************************************************************
 Load game.ruleset file
 **************************************************************************/
 static void load_ruleset_game(char *ruleset_subdir)
@@ -2184,6 +2263,8 @@
     game.rgame.granary_food_inc = 100;
   }
 
+  game.rgame.init_techs = secfile_lookup_init_techs (&file);
+  
   section_file_check_unused(&file, filename);
   section_file_free(&file);
 }
@@ -2456,6 +2537,10 @@
       packet.leader_sex[i] = n->leader_is_male[i];
     }
     packet.city_style = n->city_style;
+    for (i = 0; n->init_techs[i] != A_LAST; i++) {
+      packet.init_techs[i] = n->init_techs[i];
+    }
+    packet.init_techs[i+1] = A_LAST; /* A_LAST terminate */
 
     lsend_packet_ruleset_nation(dest, &packet);
   }
@@ -2490,6 +2575,7 @@
 static void send_ruleset_game(struct conn_list *dest)
 {
   struct packet_ruleset_game misc_p;
+  int i;
 
   misc_p.min_city_center_food = game.rgame.min_city_center_food;
   misc_p.min_city_center_shield = game.rgame.min_city_center_shield;
@@ -2501,6 +2587,10 @@
   misc_p.nuke_contamination = game.rgame.nuke_contamination;
   misc_p.granary_food_ini = game.rgame.granary_food_ini;
   misc_p.granary_food_inc = game.rgame.granary_food_inc;
+  for (i = 0; game.rgame.init_techs[i] != A_LAST; i++) {
+    misc_p.init_techs[i] = game.rgame.init_techs[i];
+  }
+  misc_p.init_techs[i+1] = A_LAST; /* A_LAST terminate */
 
   lsend_packet_ruleset_game(dest, &misc_p);
 }
@@ -2514,7 +2604,6 @@
   struct section_file cityfile, nationfile;
 
   freelog(LOG_NORMAL, _("Loading rulesets"));
-  load_ruleset_game(game.ruleset.game);
 
   openload_ruleset_file(&techfile, game.ruleset.techs, "techs");
   load_tech_names(&techfile);
@@ -2544,6 +2633,7 @@
   load_ruleset_terrain(&terrfile);
   load_ruleset_buildings(&buildfile);
   load_ruleset_nations(&nationfile);
+  load_ruleset_game(game.ruleset.game);
   translate_data_names();
 }
 

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