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

 This patch adds requirement vector for bases. This replaces tech
flags TF_FORTRESS and TF_AIRBASE.


 - ML

diff -Nurd -X.diff_ignore freeciv/client/helpdata.c freeciv/client/helpdata.c
--- freeciv/client/helpdata.c	2007-02-26 14:16:19.000000000 +0200
+++ freeciv/client/helpdata.c	2007-03-01 00:48:13.000000000 +0200
@@ -869,21 +869,8 @@
     }
 
     /* Fortress. */
-    switch (techs_with_flag_string(TF_FORTRESS, buf2, sizeof(buf2))) {
-    case 0:
-      sprintf(buf + strlen(buf), _("* Can build fortresses.\n"));
-      break;
-    case 1:
-      sprintf(buf + strlen(buf),
-	      _("* Can build fortresses (if %s is known).\n"), buf2);
-      break;
-    default:
-      sprintf(buf + strlen(buf),
-	      _("* Can build fortresses (if any of the following are "
-		"known: %s).\n"), buf2);
-      break;
-    }
-
+    sprintf(buf + strlen(buf), _("* Can build fortresses.\n"));
+ 
     /* Pollution, fallout. */
     sprintf(buf + strlen(buf), _("* Can clean pollution from tiles.\n"));
     sprintf(buf + strlen(buf),
@@ -1134,22 +1121,6 @@
     free((void *) units_str);
   }
 
-  if (tech_flag(i, TF_FORTRESS)) {
-    const char *units_str = get_units_with_flag_string(F_SETTLERS);
-    sprintf(buf + strlen(buf), _("* Allows %s to build fortresses.\n"),
-	    units_str);
-    free((void *) units_str);
-  }
-
-  if (tech_flag(i, TF_AIRBASE)) {
-    const char *units_str = get_units_with_flag_string(F_AIRBASE);
-    if (units_str) {
-      sprintf(buf + strlen(buf), _("* Allows %s to build airbases.\n"),
-	      units_str);
-      free((void *) units_str);
-    }
-  }
-
   if (tech_flag(i, TF_RAILROAD)) {
     const char *units_str = get_units_with_flag_string(F_SETTLERS);
     sprintf(buf + strlen(buf),
diff -Nurd -X.diff_ignore freeciv/client/packhand.c freeciv/client/packhand.c
--- freeciv/client/packhand.c	2007-02-26 14:16:18.000000000 +0200
+++ freeciv/client/packhand.c	2007-03-01 00:22:48.000000000 +0200
@@ -2447,6 +2447,7 @@
 void handle_ruleset_base(struct packet_ruleset_base *p)
 {
   struct base_type *pbase = base_type_get_by_id(p->id);
+  int i;
 
   if (!pbase) {
     freelog(LOG_ERROR,
@@ -2458,6 +2459,11 @@
   sz_strlcpy(pbase->name_orig, p->name);
   pbase->name = Q_(pbase->name_orig);
 
+  for (i = 0; i < p->reqs_count; i++) {
+    requirement_vector_append(&pbase->reqs, &p->reqs[i]);
+  }
+  assert(pbase->reqs.size == p->reqs_count);
+
   pbase->flags = p->flags;
 }
 
diff -Nurd -X.diff_ignore freeciv/common/base.c freeciv/common/base.c
--- freeciv/common/base.c	2007-02-28 23:02:37.000000000 +0200
+++ freeciv/common/base.c	2007-03-01 00:44:38.000000000 +0200
@@ -18,6 +18,8 @@
 #include <assert.h>
 
 #include "base.h"
+#include "tile.h"
+#include "unit.h"
 
 static struct base_type base_types[BASE_LAST];
 
@@ -43,6 +45,27 @@
   return pbase->name;
 }
 
+/**************************************************************************
+  Can unit build base to given tile?
+**************************************************************************/
+bool can_build_base(const struct unit *punit, const struct base_type *pbase,
+                    const struct tile *ptile)
+{
+  if ((pbase->id == BASE_FORTRESS && !unit_flag(punit, F_SETTLERS)) ||
+      (pbase->id == BASE_AIRBASE && !unit_flag(punit, F_AIRBASE))) {
+    /* This unit cannot build this kind of base */
+    return FALSE;
+  }
+
+  if (tile_get_city(ptile)) {
+    /* Bases cannot be built inside cities */
+    return FALSE;
+  }
+
+  return are_reqs_active(unit_owner(punit), NULL, NULL, ptile,
+                         unit_type(punit), NULL, NULL, &pbase->reqs);
+}
+
 /****************************************************************************
   Determine base type from specials. Returns NULL if there is no base
 ****************************************************************************/
@@ -96,5 +119,6 @@
 
   for (i = 0; i < ARRAY_SIZE(base_types); i++) {
     base_types[i].id = i;
+    requirement_vector_init(&base_types[i].reqs);
   }
 }
diff -Nurd -X.diff_ignore freeciv/common/base.h freeciv/common/base.h
--- freeciv/common/base.h	2007-02-28 23:02:38.000000000 +0200
+++ freeciv/common/base.h	2007-03-01 00:39:01.000000000 +0200
@@ -14,6 +14,7 @@
 #define FC__BASE_H
 
 #include "fc_types.h"
+#include "requirements.h"
 #include "terrain.h"
 
 enum base_type_id { BASE_FORTRESS = 0, BASE_AIRBASE, BASE_LAST };
@@ -41,12 +42,16 @@
   const char *name;
   char name_orig[MAX_LEN_NAME];
   int id;
+  struct requirement_vector reqs;
   bv_base_flags flags;
 };
 
 bool base_flag(const struct base_type *pbase, enum base_flag_id flag);
 const char *base_name(const struct base_type *pbase);
 
+bool can_build_base(const struct unit *punit, const struct base_type *pbase,
+                    const struct tile *ptile);
+
 struct base_type *base_type_get_from_special(bv_special spe);
 
 enum base_flag_id base_flag_from_str(const char *s);
diff -Nurd -X.diff_ignore freeciv/common/packets.def freeciv/common/packets.def
--- freeciv/common/packets.def	2007-02-26 14:16:16.000000000 +0200
+++ freeciv/common/packets.def	2007-03-01 00:21:40.000000000 +0200
@@ -1270,6 +1270,8 @@
 PACKET_RULESET_BASE=120;sc,lsend
   UINT8 id;
   STRING name[MAX_LEN_NAME];
+  UINT8 reqs_count;
+  REQUIREMENT reqs[MAX_NUM_REQS:reqs_count];
   BV_BASE_FLAGS flags;
 end
 
diff -Nurd -X.diff_ignore freeciv/common/tech.c freeciv/common/tech.c
--- freeciv/common/tech.c	2007-02-26 14:16:16.000000000 +0200
+++ freeciv/common/tech.c	2007-03-01 00:34:28.000000000 +0200
@@ -40,9 +40,9 @@
 static double techcoststyle1[A_LAST];
 
 static const char *flag_names[] = {
-  "Bonus_Tech", "Bridge", "Railroad", "Fortress",
+  "Bonus_Tech", "Bridge", "Railroad",
   "Population_Pollution_Inc", 
-  "Airbase", "Farmland",
+  "Farmland",
   "Build_Airborne"
 };
 /* Note that these strings must correspond with the enums in tech_flag_id,
diff -Nurd -X.diff_ignore freeciv/common/tech.h freeciv/common/tech.h
--- freeciv/common/tech.h	2007-02-26 14:16:16.000000000 +0200
+++ freeciv/common/tech.h	2007-03-01 00:34:05.000000000 +0200
@@ -55,9 +55,7 @@
   TF_BONUS_TECH, /* player gets extra tech if rearched first */
   TF_BRIDGE,    /* "Settler" unit types can build bridges over rivers */
   TF_RAILROAD,  /* "Settler" unit types can build rail roads */
-  TF_FORTRESS,  /* "Settler" unit types can build fortress */
   TF_POPULATION_POLLUTION_INC,  /* Increase the pollution factor created by popultaion by one */
-  TF_AIRBASE,   /* "Airbase" unit types can build Airbases */
   TF_FARMLAND,  /* "Settler" unit types can build farmland */
   TF_BUILD_AIRBORNE, /* Player can build air units */
   TF_LAST
diff -Nurd -X.diff_ignore freeciv/common/unit.c freeciv/common/unit.c
--- freeciv/common/unit.c	2007-02-28 23:02:38.000000000 +0200
+++ freeciv/common/unit.c	2007-03-01 00:43:50.000000000 +0200
@@ -831,16 +831,13 @@
 
   case ACTIVITY_FORTRESS:
     pbase = tile_get_base(ptile);
-    return (unit_flag(punit, F_SETTLERS)
-	    && !tile_get_city(ptile)
-	    && player_knows_techs_with_flag(pplayer, TF_FORTRESS)
+    return (can_build_base(punit, base_type_get_by_id(BASE_FORTRESS), ptile)
 	    && (pbase == NULL || pbase->id != BASE_FORTRESS)
 	    && !is_ocean(ptile->terrain));
 
   case ACTIVITY_AIRBASE:
     pbase = tile_get_base(ptile);
-    return (unit_flag(punit, F_AIRBASE)
-	    && player_knows_techs_with_flag(pplayer, TF_AIRBASE)
+    return (can_build_base(punit, base_type_get_by_id(BASE_AIRBASE), ptile)
 	    && (pbase == NULL || pbase->id != BASE_AIRBASE)
 	    && !is_ocean(ptile->terrain));
 
diff -Nurd -X.diff_ignore freeciv/data/civ1/techs.ruleset freeciv/data/civ1/techs.ruleset
--- freeciv/data/civ1/techs.ruleset	2007-01-29 01:04:05.000000000 +0200
+++ freeciv/data/civ1/techs.ruleset	2007-03-01 00:46:10.000000000 +0200
@@ -170,7 +170,7 @@
 name     = _("Construction")
 req1     = "Masonry"
 req2     = "Currency"
-flags    = "Fortress"
+flags    = ""
 graphic     = "a.construction"
 graphic_alt = "-"
 
diff -Nurd -X.diff_ignore freeciv/data/civ1/terrain.ruleset freeciv/data/civ1/terrain.ruleset
--- freeciv/data/civ1/terrain.ruleset	2007-01-29 01:04:05.000000000 +0200
+++ freeciv/data/civ1/terrain.ruleset	2007-03-01 00:47:11.000000000 +0200
@@ -597,6 +597,8 @@
 ; fortress and airbase.
 ;
 ; name                    = Name of the base type.
+; reqs 	                  = requirements to build the base (see effects.ruleset
+;                           and README.effects for help on requirements)
 ; flags
 ;   - "NoAggressive"      = Units inside are not considered aggressive
 ;   - "DefenseBonus"      = Units inside gain defense bonus
@@ -611,10 +613,18 @@
 
 [fortress]
 name        = _("Fortress")
+reqs        =
+    { "type", "name", "range"
+      "Tech", "Construction", "Player"
+    }
 flags       = "NoAggressive", "DefenseBonus", "Watchtower", "ClaimTerritory",
               "NoStackDeath", "DiplomatDefense"
 
 [airbase]
 name        = _("Airbase")
+reqs        =
+    { "type", "name", "range"
+      "Tech", "Never", "Player"
+    }
 flags       = "NoStackDeath", "DiplomatDefense", "Refuel", "NoHPLoss",
               "AttackUnreachable", "ParadropFrom"
diff -Nurd -X.diff_ignore freeciv/data/civ2/techs.ruleset freeciv/data/civ2/techs.ruleset
--- freeciv/data/civ2/techs.ruleset	2007-02-26 14:15:35.000000000 +0200
+++ freeciv/data/civ2/techs.ruleset	2007-03-01 00:46:00.000000000 +0200
@@ -187,7 +187,7 @@
 name     = _("Construction")
 req1     = "Masonry"
 req2     = "Currency"
-flags    = "Fortress"
+flags    = ""
 graphic     = "a.construction"
 graphic_alt = "-"
 
@@ -560,7 +560,7 @@
 name     = _("Radio")
 req1     = "Flight"
 req2     = "Electricity"
-flags    = "Airbase"
+flags    = ""
 graphic     = "a.radio"
 graphic_alt = "-"
 
diff -Nurd -X.diff_ignore freeciv/data/civ2/terrain.ruleset freeciv/data/civ2/terrain.ruleset
--- freeciv/data/civ2/terrain.ruleset	2007-01-29 01:04:06.000000000 +0200
+++ freeciv/data/civ2/terrain.ruleset	2007-03-01 00:47:36.000000000 +0200
@@ -689,6 +689,8 @@
 ; fortress and airbase.
 ;
 ; name                    = Name of the base type.
+; reqs 	                  = requirements to build the base (see effects.ruleset
+;                           and README.effects for help on requirements)
 ; flags
 ;   - "NoAggressive"      = Units inside are not considered aggressive
 ;   - "DefenseBonus"      = Units inside gain defense bonus
@@ -703,10 +705,18 @@
 
 [fortress]
 name        = _("Fortress")
+reqs        =
+    { "type", "name", "range"
+      "Tech", "Construction", "Player"
+    }
 flags       = "NoAggressive", "DefenseBonus", "Watchtower", "ClaimTerritory",
               "NoStackDeath", "DiplomatDefense"
 
 [airbase]
 name        = _("Airbase")
+reqs        =
+    { "type", "name", "range"
+      "Tech", "Radio", "Player"
+    }
 flags       = "NoStackDeath", "DiplomatDefense", "Refuel", "NoHPLoss",
               "AttackUnreachable", "ParadropFrom"
diff -Nurd -X.diff_ignore freeciv/data/default/techs.ruleset freeciv/data/default/techs.ruleset
--- freeciv/data/default/techs.ruleset	2007-02-26 14:15:37.000000000 +0200
+++ freeciv/data/default/techs.ruleset	2007-03-01 00:45:25.000000000 +0200
@@ -45,10 +45,8 @@
 ; "Bridge"   = "Settler" unit types can build bridges over rivers
 ; "Railroad" = "Settler" unit types can build rail roads
 ; "Farmland" = "Settler" unit types can build farmland
-; "Fortress" = "Settler" unit types can build fortress
 ; "Population_Pollution_Inc" = Increase the pollution factor created by
 ;                              popultaion by one
-; "Airbase" = "Airbase" unit types can build Airbases
 ; "Build_Airborne" = from now on can build air units (for use by AI)
 
 [advance_advanced_flight]
@@ -200,7 +198,7 @@
 name     = _("Construction")
 req1     = "Masonry"
 req2     = "Currency"
-flags    = "Fortress"
+flags    = ""
 graphic     = "a.construction"
 graphic_alt = "-"
 
@@ -565,7 +563,7 @@
 name     = _("Radio")
 req1     = "Flight"
 req2     = "Electricity"
-flags    = "Airbase"
+flags    = ""
 graphic     = "a.radio"
 graphic_alt = "-"
 
diff -Nurd -X.diff_ignore freeciv/data/default/terrain.ruleset freeciv/data/default/terrain.ruleset
--- freeciv/data/default/terrain.ruleset	2007-02-12 15:27:42.000000000 +0200
+++ freeciv/data/default/terrain.ruleset	2007-03-01 00:19:02.000000000 +0200
@@ -756,6 +756,8 @@
 ; fortress and airbase.
 ;
 ; name                    = Name of the base type.
+; reqs 	                  = requirements to build the base (see effects.ruleset
+;                           and README.effects for help on requirements)
 ; flags
 ;   - "NoAggressive"      = Units inside are not considered aggressive
 ;   - "DefenseBonus"      = Units inside gain defense bonus
@@ -770,10 +772,18 @@
 
 [fortress]
 name        = _("Fortress")
+reqs        =
+    { "type", "name", "range"
+      "Tech", "Construction", "Player"
+    }
 flags       = "NoAggressive", "DefenseBonus", "Watchtower", "ClaimTerritory",
               "NoStackDeath", "DiplomatDefense"
 
 [airbase]
 name        = _("Airbase")
+reqs        =
+    { "type", "name", "range"
+      "Tech", "Radio", "Player"
+    }
 flags       = "NoStackDeath", "DiplomatDefense", "Refuel", "NoHPLoss",
               "AttackUnreachable", "ParadropFrom"
diff -Nurd -X.diff_ignore freeciv/server/ruleset.c freeciv/server/ruleset.c
--- freeciv/server/ruleset.c	2007-02-28 23:02:37.000000000 +0200
+++ freeciv/server/ruleset.c	2007-03-01 00:21:11.000000000 +0200
@@ -1787,6 +1787,7 @@
     char **slist;
     int j;
     char *section;
+    struct requirement_vector *reqs;
 
     pbase->name = Q_(pbase->name_orig);
 
@@ -1795,9 +1796,12 @@
     } else if (pbase->id == BASE_AIRBASE) {
       section = "airbase";
     } else {
-      freelog(LOG_ERROR, "Unhandled base type in loas_ruleset_terrain()");
+      freelog(LOG_ERROR, "Unhandled base type in load_ruleset_terrain()");
       exit(EXIT_FAILURE);
     }
+    reqs = lookup_req_list(file, section, "reqs");
+    requirement_vector_copy(&pbase->reqs, reqs);
+
     slist = secfile_lookup_str_vec(file, &nval, "%s.flags", section);
     BV_CLR_ALL(pbase->flags);
     for (j = 0; j < nval; j++) {
@@ -3051,8 +3055,17 @@
   struct packet_ruleset_base packet;
 
   base_type_iterate(b) {
+    int j;
+
     packet.id = b->id;
     sz_strlcpy(packet.name, b->name);
+
+    j = 0;
+    requirement_vector_iterate(&b->reqs, preq) {
+      packet.reqs[j++] = *preq;
+    } requirement_vector_iterate_end;
+    packet.reqs_count = j;
+
     packet.flags = b->flags;
 
     lsend_packet_ruleset_base(dest, &packet);
diff -Nurd -X.diff_ignore freeciv/version.in freeciv/version.in
--- freeciv/version.in	2007-02-26 14:16:19.000000000 +0200
+++ freeciv/version.in	2007-03-01 00:31:15.000000000 +0200
@@ -24,4 +24,4 @@
 #   - Avoid adding a new manditory capbility to the development branch for
 #     as long as possible.  We want to maintain network compatibility with
 #     the stable branch for as long as possible.
-FREECIV_NETWORK_CAPSTRING("+Freeciv.Devel.2007.Feb.17c")
+FREECIV_NETWORK_CAPSTRING("+Freeciv.Devel.2007.Mar.01")
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to