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

On 1/21/07, Marko Lindqvist <[EMAIL PROTECTED]> wrote:
>
> On 1/19/07, Marko Lindqvist <[EMAIL PROTECTED]> wrote:
> >
> >  Applies on top of #33876.
>
>  - Improvet ruleset comments
>  - Send information to client

 - Updated against latest version of #33876
 - Each base now has special section name in ruleset ([fortress] and
[airbase]) instead of [base_<name>]. Previous generic format was just
silly considering all the limitations base implementation currently
has.


 - ML

diff -Nurd -X.diff_ignore freeciv/client/packhand.c freeciv/client/packhand.c
--- freeciv/client/packhand.c	2007-01-21 00:49:15.000000000 +0200
+++ freeciv/client/packhand.c	2007-01-21 17:52:58.000000000 +0200
@@ -2441,6 +2441,26 @@
   tileset_setup_resource(tileset, presource);
 }
 
+/****************************************************************************
+  Handle a packet about a particular base type.
+****************************************************************************/
+void handle_ruleset_base(struct packet_ruleset_base *p)
+{
+  struct base_type *pbase = base_type_get_by_id(p->id);
+
+  if (!pbase) {
+    freelog(LOG_ERROR,
+            "Received bad base id %d in handle_ruleset_base",
+            p->id);
+    return;
+  }
+
+  sz_strlcpy(pbase->name_orig, p->name);
+  pbase->name = Q_(pbase->name_orig);
+
+  pbase->flags = p->flags;
+}
+
 /**************************************************************************
   Handle the terrain control ruleset packet sent by the server.
 **************************************************************************/
diff -Nurd -X.diff_ignore freeciv/common/base.c freeciv/common/base.c
--- freeciv/common/base.c	2007-01-21 17:52:40.000000000 +0200
+++ freeciv/common/base.c	2007-01-21 18:11:34.000000000 +0200
@@ -19,52 +19,59 @@
 
 #include "base.h"
 
+static struct base_type base_types[BASE_LAST];
+
+static const char *base_type_flag_names[] = {
+  "NoAggressive", "DefenseBonus", "NoStackDeath", "Watchtower",
+  "ClaimTerritory", "DiplomatDefense", "Refuel", "NoHPLoss",
+  "AttackUnreachable", "ParadropFrom"
+};
+
 /****************************************************************************
   Check if base provides effect
 ****************************************************************************/
-bool base_flag(Base_type_id base_type, enum base_flag_id flag)
+bool base_flag(const struct base_type *pbase, enum base_flag_id flag)
 {
-  switch(base_type) {
-  case BASE_FORTRESS:
-    /* Fortress */
-    switch(flag) {
-    case BF_NOT_AGGRESSIVE:
-    case BF_DEFENSE_BONUS:
-    case BF_WATCHTOWER:
-    case BF_CLAIM_TERRITORY:
-    case BF_NO_STACK_DEATH:
-    case BF_DIPLOMAT_DEFENSE:
-      return TRUE;
+  return BV_ISSET(pbase->flags, flag);
+}
 
-    case BF_REFUEL:
-    case BF_NO_HP_LOSS:
-    case BF_ATTACK_UNREACHABLE:
-    case BF_PARADROP_FROM:
-    case BF_LAST:
-      return FALSE;
+/**************************************************************************
+  Convert base flag names to enum; case insensitive;
+  returns BF_LAST if can't match.
+**************************************************************************/
+enum base_flag_id base_flag_from_str(const char *s)
+{
+  enum base_flag_id i;
+  
+  assert(ARRAY_SIZE(base_type_flag_names) == BF_LAST);
+  
+  for(i = 0; i < BF_LAST; i++) {
+    if (mystrcasecmp(base_type_flag_names[i], s)==0) {
+      return i;
     }
-    break;
+  }
+  return BF_LAST;
+}
+  
+/****************************************************************************
+  Returns base type structure for an ID value.
+****************************************************************************/
+struct base_type *base_type_get_by_id(Base_type_id id)
+{
+  if (id < 0 || id >= BASE_LAST) {
+    return NULL;
+  }
+  return &base_types[id];
+}
 
-  case BASE_AIRBASE:
-    /* Airbase */
-    switch(flag) {
-    case BF_NO_STACK_DEATH:
-    case BF_DIPLOMAT_DEFENSE:
-    case BF_REFUEL:
-    case BF_NO_HP_LOSS:
-    case BF_ATTACK_UNREACHABLE:
-    case BF_PARADROP_FROM:
-      return TRUE;
+/****************************************************************************
+  Inialize base_type structures.
+****************************************************************************/
+void base_types_init(void)
+{
+  int i;
 
-    case BF_NOT_AGGRESSIVE:
-    case BF_DEFENSE_BONUS:
-    case BF_WATCHTOWER:
-    case BF_CLAIM_TERRITORY:
-    case BF_LAST:
-      return FALSE;
-    }
-    break;
+  for (i = 0; i < ARRAY_SIZE(base_types); i++) {
+    base_types[i].id = i;
   }
-
-  return FALSE;
 }
diff -Nurd -X.diff_ignore freeciv/common/base.h freeciv/common/base.h
--- freeciv/common/base.h	2007-01-21 17:52:40.000000000 +0200
+++ freeciv/common/base.h	2007-01-21 18:13:54.000000000 +0200
@@ -15,7 +15,7 @@
 
 #include "fc_types.h"
 
-enum base_type_id { BASE_FORTRESS, BASE_AIRBASE };
+enum base_type_id { BASE_FORTRESS = 0, BASE_AIRBASE, BASE_LAST };
 
 typedef enum base_type_id Base_type_id;
 
@@ -34,6 +34,31 @@
   BF_LAST                /* This has to be last */
 };
 
-bool base_flag(Base_type_id base_type, enum base_flag_id flag);
+BV_DEFINE(bv_base_flags, BF_LAST);
+
+struct base_type {
+  const char *name;
+  char name_orig[MAX_LEN_NAME];
+  int id;
+  bv_base_flags flags;
+};
+
+bool base_flag(const struct base_type *pbase, enum base_flag_id flag);
+enum base_flag_id base_flag_from_str(const char *s);
+struct base_type *base_type_get_by_id(Base_type_id id);
+
+void base_types_init(void);
+
+#define base_type_iterate(pbase)                                            \
+{                                                                           \
+  int _index;                                                               \
+                                                                            \
+  for (_index = 0; _index < BASE_LAST; _index++) {                          \
+    struct base_type *pbase = base_type_get_by_id(_index);
+
+#define base_type_iterate_end                                               \
+  }                                                                         \
+}
+
 
 #endif  /* FC__BASE_H */
diff -Nurd -X.diff_ignore freeciv/common/game.c freeciv/common/game.c
--- freeciv/common/game.c	2007-01-21 00:49:15.000000000 +0200
+++ freeciv/common/game.c	2007-01-21 17:52:58.000000000 +0200
@@ -17,6 +17,7 @@
 
 #include <assert.h>
 
+#include "base.h"
 #include "capstr.h"
 #include "city.h"
 #include "cm.h"
@@ -288,6 +289,7 @@
   init_our_capability();    
   map_init();
   terrains_init();
+  base_types_init();
   improvements_init();
   techs_init();
   unit_classes_init();
diff -Nurd -X.diff_ignore freeciv/common/packets.def freeciv/common/packets.def
--- freeciv/common/packets.def	2007-01-21 00:49:15.000000000 +0200
+++ freeciv/common/packets.def	2007-01-21 17:52:58.000000000 +0200
@@ -199,6 +199,7 @@
 type BV_FLAGS		= bitvector(bv_flags)
 type BV_ROLES		= bitvector(bv_roles)
 type BV_TERRAIN_FLAGS	= bitvector(bv_terrain_flags)
+type BV_BASE_FLAGS      = bitvector(bv_base_flags)
 type BV_CITY_OPTIONS    = bitvector(bv_city_options)
 type BV_SPECIAL         = bitvector(bv_special)
 type BV_PLAYER          = bitvector(bv_player)
@@ -1267,6 +1268,12 @@
   BV_UCLASS_FLAGS flags;
 end
 
+PACKET_RULESET_BASE=120;sc,lsend
+  UINT8 id;
+  STRING name[MAX_LEN_NAME];
+  BV_BASE_FLAGS flags;
+end
+
 /*********************************************************
   Ruleset control values: single values, some of which are
   needed before sending other ruleset data (eg,
diff -Nurd -X.diff_ignore freeciv/common/tile.c freeciv/common/tile.c
--- freeciv/common/tile.c	2007-01-21 17:52:40.000000000 +0200
+++ freeciv/common/tile.c	2007-01-21 17:58:28.000000000 +0200
@@ -104,9 +104,9 @@
 bool tile_has_base_flag(const struct tile *ptile, enum base_flag_id flag)
 {
   return (tile_has_special(ptile, S_FORTRESS)
-          && base_flag(BASE_FORTRESS, flag))
+          && base_flag(base_type_get_by_id(BASE_FORTRESS), flag))
     || (tile_has_special(ptile, S_AIRBASE)
-        && base_flag(BASE_AIRBASE, flag));
+        && base_flag(base_type_get_by_id(BASE_AIRBASE), flag));
 }
 
 /****************************************************************************
diff -Nurd -X.diff_ignore freeciv/data/civ1/terrain.ruleset freeciv/data/civ1/terrain.ruleset
--- freeciv/data/civ1/terrain.ruleset	2007-01-21 00:49:15.000000000 +0200
+++ freeciv/data/civ1/terrain.ruleset	2007-01-21 18:13:30.000000000 +0200
@@ -592,3 +592,29 @@
 graphic_alt = "-"
 identifier  = "S"
 food        = 2
+
+; Below has to be definition for exactly two base types:
+; fortress and airbase.
+;
+; name                    = Name of the base type. Not yet used
+; flags
+;   - "NoAggressive"      = Units inside are not considered aggressive
+;   - "DefenseBonus"      = Units inside gain defense bonus
+;   - "NoStackDeath"      = Units inside do not die all at once when attacked
+;   - "Watchtower"        = Units inside see further if required tech known
+;   - "ClaimTerritory"    = Base will claim land ownership
+;   - "DiplomatDefense"   = Diplomats inside get bonus to diplomatic defense
+;   - "Refuel"            = Units can refuel at base
+;   - "NoHPLoss"          = Units inside avoid HP loss over time
+;   - "AttackUnreachable" = Unreachable units inside can be attacked
+;   - "ParadropFrom"      = Paradrop can be initiated from base
+
+[fortress]
+name        = _("Fortress")
+flags       = "NoAggressive", "DefenseBonus", "Watchtower", "ClaimTerritory",
+              "NoStackDeath", "DiplomatDefense"
+
+[airbase]
+name        = _("Airbase")
+flags       = "NoStackDeath", "DiplomatDefense", "Refuel", "NoHPLoss",
+              "AttackUnreachable", "ParadropFrom"
diff -Nurd -X.diff_ignore freeciv/data/civ2/terrain.ruleset freeciv/data/civ2/terrain.ruleset
--- freeciv/data/civ2/terrain.ruleset	2007-01-21 00:49:15.000000000 +0200
+++ freeciv/data/civ2/terrain.ruleset	2007-01-21 18:13:04.000000000 +0200
@@ -684,3 +684,29 @@
 food        = 1
 trade       = 3
 identifier  = "u"
+
+; Below has to be definition for exactly two base types:
+; fortress and airbase.
+;
+; name                    = Name of the base type. Not yet used
+; flags
+;   - "NoAggressive"      = Units inside are not considered aggressive
+;   - "DefenseBonus"      = Units inside gain defense bonus
+;   - "NoStackDeath"      = Units inside do not die all at once when attacked
+;   - "Watchtower"        = Units inside see further if required tech known
+;   - "ClaimTerritory"    = Base will claim land ownership
+;   - "DiplomatDefense"   = Diplomats inside get bonus to diplomatic defense
+;   - "Refuel"            = Units can refuel at base
+;   - "NoHPLoss"          = Units inside avoid HP loss over time
+;   - "AttackUnreachable" = Unreachable units inside can be attacked
+;   - "ParadropFrom"      = Paradrop can be initiated from base
+
+[fortress]
+name        = _("Fortress")
+flags       = "NoAggressive", "DefenseBonus", "Watchtower", "ClaimTerritory",
+              "NoStackDeath", "DiplomatDefense"
+
+[airbase]
+name        = _("Airbase")
+flags       = "NoStackDeath", "DiplomatDefense", "Refuel", "NoHPLoss",
+              "AttackUnreachable", "ParadropFrom"
diff -Nurd -X.diff_ignore freeciv/data/default/terrain.ruleset freeciv/data/default/terrain.ruleset
--- freeciv/data/default/terrain.ruleset	2007-01-21 00:49:15.000000000 +0200
+++ freeciv/data/default/terrain.ruleset	2007-01-21 18:12:33.000000000 +0200
@@ -753,3 +753,29 @@
 food        = 1
 trade       = 3
 identifier  = "u"
+
+; Below has to be definition for exactly two base types:
+; fortress and airbase.
+;
+; name                    = Name of the base type. Not yet used
+; flags
+;   - "NoAggressive"      = Units inside are not considered aggressive
+;   - "DefenseBonus"      = Units inside gain defense bonus
+;   - "NoStackDeath"      = Units inside do not die all at once when attacked
+;   - "Watchtower"        = Units inside see further if required tech known
+;   - "ClaimTerritory"    = Base will claim land ownership
+;   - "DiplomatDefense"   = Diplomats inside get bonus to diplomatic defense
+;   - "Refuel"            = Units can refuel at base
+;   - "NoHPLoss"          = Units inside avoid HP loss over time
+;   - "AttackUnreachable" = Unreachable units inside can be attacked
+;   - "ParadropFrom"      = Paradrop can be initiated from base
+
+[fortress]
+name        = _("Fortress")
+flags       = "NoAggressive", "DefenseBonus", "Watchtower", "ClaimTerritory",
+              "NoStackDeath", "DiplomatDefense"
+
+[airbase]
+name        = _("Airbase")
+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-01-21 00:49:15.000000000 +0200
+++ freeciv/server/ruleset.c	2007-01-21 18:17:06.000000000 +0200
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "base.h"
 #include "capability.h"
 #include "city.h"
 #include "fcintl.h"
@@ -100,6 +101,7 @@
 static void send_ruleset_buildings(struct conn_list *dest);
 static void send_ruleset_terrain(struct conn_list *dest);
 static void send_ruleset_resources(struct conn_list *dest);
+static void send_ruleset_bases(struct conn_list *dest);
 static void send_ruleset_governments(struct conn_list *dest);
 static void send_ruleset_cities(struct conn_list *dest);
 static void send_ruleset_game(struct conn_list *dest);
@@ -1515,6 +1517,26 @@
 
   free(sec);
 
+  base_type_iterate(pbase) {
+    char *name;
+    char *section;
+
+    if (pbase->id == BASE_FORTRESS) {
+      section = "fortress";
+    } else if (pbase->id == BASE_AIRBASE) {
+      section = "airbase";
+    } else {
+      freelog(LOG_ERROR, "Unhandled base type in load_names()");
+      exit(EXIT_FAILURE);
+    }
+    name = secfile_lookup_str(file, "%s.name", section);
+    if (name == NULL) {
+      freelog(LOG_ERROR, "Base section [%s] missing.", section);
+      exit(EXIT_FAILURE);
+    }
+
+    name_strlcpy(pbase->name_orig, name);
+  } base_type_iterate_end;
 }
 
 /**************************************************************************
@@ -1738,6 +1760,7 @@
 
     pterrain->helptext = lookup_helptext(file, tsec[i]);
   } terrain_type_iterate_end;
+  free(tsec);
 
   rsec = secfile_get_secnames_prefix(file, "resource_", &nval);
   resource_type_iterate(presource) {
@@ -1771,9 +1794,42 @@
       }
     }
   } resource_type_iterate_end;
-  free(tsec);
   free(rsec);
 
+  base_type_iterate(pbase) {
+    char **slist;
+    int j;
+    char *section;
+
+    pbase->name = Q_(pbase->name_orig);
+
+    if (pbase->id == BASE_FORTRESS) {
+      section = "fortress";
+    } else if (pbase->id == BASE_AIRBASE) {
+      section = "airbase";
+    } else {
+      freelog(LOG_ERROR, "Unhandled base type in loas_ruleset_terrain()");
+      exit(EXIT_FAILURE);
+    }
+    slist = secfile_lookup_str_vec(file, &nval, "%s.flags", section);
+    BV_CLR_ALL(pbase->flags);
+    for (j = 0; j < nval; j++) {
+      const char *sval = slist[j];
+      enum base_flag_id flag = base_flag_from_str(sval);
+
+      if (flag == BF_LAST) {
+        /* TRANS: message for an obscure ruleset error. */
+        freelog(LOG_FATAL, _("Base %s has unknown flag %s"),
+                pbase->name, sval);
+        exit(EXIT_FAILURE);
+      } else {
+        BV_SET(pbase->flags, flag);
+      }
+    }
+    
+    free(slist);
+  } base_type_iterate_end;
+
   section_file_check_unused(file, filename);
   section_file_free(file);
 }
@@ -2990,6 +3046,23 @@
 }
 
 /**************************************************************************
+  Send the base ruleset information (all individual base types) to the
+  specified connections.
+**************************************************************************/
+static void send_ruleset_bases(struct conn_list *dest)
+{
+  struct packet_ruleset_base packet;
+
+  base_type_iterate(b) {
+    packet.id = b->id;
+    sz_strlcpy(packet.name, b->name);
+    packet.flags = b->flags;
+
+    lsend_packet_ruleset_base(dest, &packet);
+  } base_type_iterate_end;
+}
+
+/**************************************************************************
   Send the government ruleset information to the specified connections.
   One packet per government type, and for each type one per ruler title.
 **************************************************************************/
@@ -3245,6 +3318,7 @@
   send_ruleset_specialists(dest);
   send_ruleset_resources(dest);
   send_ruleset_terrain(dest);
+  send_ruleset_bases(dest);
   send_ruleset_buildings(dest);
   send_ruleset_nations(dest);
   send_ruleset_cities(dest);
diff -Nurd -X.diff_ignore freeciv/server/unittools.c freeciv/server/unittools.c
--- freeciv/server/unittools.c	2007-01-21 17:52:40.000000000 +0200
+++ freeciv/server/unittools.c	2007-01-21 17:54:28.000000000 +0200
@@ -1254,9 +1254,9 @@
   if ((is_allied_city_tile(ptile, pplayer)
        && !is_non_allied_unit_tile(ptile, pplayer))
       || (((contains_special(plrtile->special, S_FORTRESS)
-            && base_flag(BASE_FORTRESS, BF_REFUEL))
+            && base_flag(base_type_get_by_id(BASE_FORTRESS), BF_REFUEL))
            || (contains_special(plrtile->special, S_AIRBASE)
-               && base_flag(BASE_AIRBASE, BF_REFUEL)))
+               && base_flag(base_type_get_by_id(BASE_AIRBASE), BF_REFUEL)))
 	  && !is_non_allied_unit_tile(ptile, pplayer)))
     return TRUE;
 
diff -Nurd -X.diff_ignore freeciv/version.in freeciv/version.in
--- freeciv/version.in	2007-01-21 00:49:16.000000000 +0200
+++ freeciv/version.in	2007-01-21 17:52:58.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.Jan.20")
+FREECIV_NETWORK_CAPSTRING("+Freeciv.Devel.2007.Jan.21")
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to