Author: jtn
Date: Mon Jun  9 10:49:20 2014
New Revision: 25105

URL: http://svn.gna.org/viewcvs/freeciv?rev=25105&view=rev
Log:
Document embark/disembark restrictions and exceptions in autogenerated
unit help.

See gna bug #22143.

Modified:
    branches/S2_5/client/helpdata.c
    branches/S2_5/common/unit.c
    branches/S2_5/common/unittype.c
    branches/S2_5/common/unittype.h

Modified: branches/S2_5/client/helpdata.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/helpdata.c?rev=25105&r1=25104&r2=25105&view=diff
==============================================================================
--- branches/S2_5/client/helpdata.c     (original)
+++ branches/S2_5/client/helpdata.c     Mon Jun  9 10:49:20 2014
@@ -2281,9 +2281,143 @@
                      utype->transport_capacity),
                  utype->transport_capacity, astr_str(&list));
     astr_free(&list);
+    if (uclass_has_flag(utype_class(utype), UCF_UNREACHABLE)) {
+      /* Document restrictions on when units can load/unload */
+      bool has_restricted_load = FALSE, has_unrestricted_load = FALSE,
+           has_restricted_unload = FALSE, has_unrestricted_unload = FALSE;
+      unit_type_iterate(pcargo) {
+        if (can_unit_type_transport(utype, utype_class(pcargo))) {
+          if (utype_can_freely_load(pcargo, utype)) {
+            has_unrestricted_load = TRUE;
+          } else {
+            has_restricted_load = TRUE;
+          }
+          if (utype_can_freely_unload(pcargo, utype)) {
+            has_unrestricted_unload = TRUE;
+          } else {
+            has_restricted_unload = TRUE;
+          }
+        }
+      } unit_type_iterate_end;
+      if (has_restricted_load) {
+        if (has_unrestricted_load) {
+          /* At least one type of cargo can load onto us freely.
+           * The specific exceptions will be documented in cargo help. */
+          CATLSTR(buf, bufsz,
+                  _("  * Some cargo cannot be loaded except in a city or a "
+                    "base native to this transport.\n"));
+        } else {
+          /* No exceptions */
+          CATLSTR(buf, bufsz,
+                  _("  * Cargo cannot be loaded except in a city or a "
+                    "base native to this transport.\n"));
+        }
+      } /* else, no restricted cargo exists; keep quiet */
+      if (has_restricted_unload) {
+        if (has_unrestricted_unload) {
+          /* At least one type of cargo can unload from us freely. */
+          CATLSTR(buf, bufsz,
+                  _("  * Some cargo cannot be unloaded except in a city or a "
+                    "base native to this transport.\n"));
+        } else {
+          /* No exceptions */
+          CATLSTR(buf, bufsz,
+                  _("  * Cargo cannot be unloaded except in a city or a "
+                    "base native to this transport.\n"));
+        }
+      } /* else, no restricted cargo exists; keep quiet */
+    }
   }
   if (utype_has_flag(utype, UTYF_TRIREME)) {
     CATLSTR(buf, bufsz, _("* Must stay next to coast.\n"));
+  }
+  {
+    /* Document exceptions to embark/disembark restrictions that we
+     * have as cargo. */
+    bv_unit_classes embarks, disembarks;
+    BV_CLR_ALL(embarks);
+    BV_CLR_ALL(disembarks);
+    /* Determine which of our transport classes have restrictions in the first
+     * place (that is, contain at least one transport which carries at least
+     * one type of cargo which is restricted).
+     * We'll suppress output for classes not in this set, since this cargo
+     * type is not behaving exceptionally in such cases. */
+    unit_type_iterate(utrans) {
+      const Unit_Class_id trans_class = uclass_index(utype_class(utrans));
+      /* Don't waste time repeating checks on classes we've already checked,
+       * or weren't under consideration in the first place */
+      if (!BV_ISSET(embarks, trans_class)
+          && BV_ISSET(utype->embarks, trans_class)) {
+        unit_type_iterate(other_cargo) {
+          if (can_unit_type_transport(utrans, utype_class(other_cargo))
+              && !utype_can_freely_load(other_cargo, utrans)) {
+            /* At least one load restriction in transport class, which
+             * we aren't subject to */
+            BV_SET(embarks, trans_class);
+          }
+        } unit_type_iterate_end; /* cargo */
+      }
+      if (!BV_ISSET(disembarks, trans_class)
+          && BV_ISSET(utype->disembarks, trans_class)) {
+        unit_type_iterate(other_cargo) {
+          if (can_unit_type_transport(utrans, utype_class(other_cargo))
+              && !utype_can_freely_unload(other_cargo, utrans)) {
+            /* At least one load restriction in transport class, which
+             * we aren't subject to */
+            BV_SET(disembarks, trans_class);
+          }
+        } unit_type_iterate_end; /* cargo */
+      }
+    } unit_class_iterate_end; /* transports */
+
+    if (BV_ISSET_ANY(embarks)) {
+      /* Build list of embark exceptions */
+      const char *eclasses[uclass_count()];
+      int i = 0;
+      struct astring elist = ASTRING_INIT;
+
+      unit_class_iterate(uclass) {
+        if (BV_ISSET(embarks, uclass_index(uclass))) {
+          eclasses[i++] = uclass_name_translation(uclass);
+        }
+      } unit_class_iterate_end;
+      astr_build_or_list(&elist, eclasses, i);
+      if (BV_ARE_EQUAL(embarks, disembarks)) {
+        /* A common case: the list of disembark exceptions is identical */
+        cat_snprintf(buf, bufsz,
+                     /* TRANS: %s is a list of unit classes separated
+                      * by "or". */
+                     _("* May load onto and unload from %s transports even "
+                       "when underway.\n"),
+                     astr_str(&elist));
+      } else {
+        cat_snprintf(buf, bufsz,
+                     /* TRANS: %s is a list of unit classes separated
+                      * by "or". */
+                     _("* May load onto %s transports even when underway.\n"),
+                     astr_str(&elist));
+      }
+      astr_free(&elist);
+    }
+    if (BV_ISSET_ANY(disembarks) && !BV_ARE_EQUAL(embarks, disembarks)) {
+      /* Build list of disembark exceptions (if different from embarking) */
+      const char *dclasses[uclass_count()];
+      int i = 0;
+      struct astring dlist = ASTRING_INIT;
+
+      unit_class_iterate(uclass) {
+        if (BV_ISSET(disembarks, uclass_index(uclass))) {
+          dclasses[i++] = uclass_name_translation(uclass);
+        }
+      } unit_class_iterate_end;
+      astr_build_or_list(&dlist, dclasses, i);
+      cat_snprintf(buf, bufsz,
+                   /* TRANS: %s is a list of unit classes separated
+                    * by "or". */
+                   _("* May unload from %s transports even when underway.\n"),
+                   astr_str(&dlist));
+      astr_free(&dlist);
+    }
   }
   if (utype_has_flag(utype, UTYF_TRADE_ROUTE)) {
     cat_snprintf(buf, bufsz,

Modified: branches/S2_5/common/unit.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/unit.c?rev=25105&r1=25104&r2=25105&view=diff
==============================================================================
--- branches/S2_5/common/unit.c (original)
+++ branches/S2_5/common/unit.c Mon Jun  9 10:49:20 2014
@@ -825,7 +825,7 @@
   }
 
   /* Un-embarkable transport must be in city or base to load cargo. */
-  if (!BV_ISSET(unit_type(pcargo)->embarks, uclass_index(unit_class(ptrans)))
+  if (!utype_can_freely_load(unit_type(pcargo), unit_type(ptrans))
       && !tile_city(unit_tile(ptrans))
       && !tile_has_native_base(unit_tile(ptrans), unit_type(ptrans))) {
     return FALSE;
@@ -895,7 +895,7 @@
   }
 
   /* Un-disembarkable transport must be in city or base to unload cargo. */
-  if (!BV_ISSET(unit_type(pcargo)->disembarks, 
uclass_index(unit_class(ptrans)))
+  if (!utype_can_freely_unload(unit_type(pcargo), unit_type(ptrans))
       && !tile_city(unit_tile(ptrans))
       && !tile_has_native_base(unit_tile(ptrans), unit_type(ptrans))) {
     return FALSE;

Modified: branches/S2_5/common/unittype.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/unittype.c?rev=25105&r1=25104&r2=25105&view=diff
==============================================================================
--- branches/S2_5/common/unittype.c     (original)
+++ branches/S2_5/common/unittype.c     Mon Jun  9 10:49:20 2014
@@ -234,6 +234,30 @@
 }
 
 /****************************************************************************
+  Return TRUE iff the given cargo type has no restrictions on when it can
+  load onto the given transporter.
+  (Does not check that cargo is valid for transport!)
+****************************************************************************/
+bool utype_can_freely_load(const struct unit_type *pcargotype,
+                           const struct unit_type *ptranstype)
+{
+  return BV_ISSET(pcargotype->embarks,
+                  uclass_index(utype_class(ptranstype)));
+}
+
+/****************************************************************************
+  Return TRUE iff the given cargo type has no restrictions on when it can
+  unload from the given transporter.
+  (Does not check that cargo is valid for transport!)
+****************************************************************************/
+bool utype_can_freely_unload(const struct unit_type *pcargotype,
+                             const struct unit_type *ptranstype)
+{
+  return BV_ISSET(pcargotype->disembarks,
+                  uclass_index(utype_class(ptranstype)));
+}
+
+/****************************************************************************
   Returns the number of shields it takes to build this unit type.
 ****************************************************************************/
 int utype_build_shield_cost(const struct unit_type *punittype)

Modified: branches/S2_5/common/unittype.h
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/unittype.h?rev=25105&r1=25104&r2=25105&view=diff
==============================================================================
--- branches/S2_5/common/unittype.h     (original)
+++ branches/S2_5/common/unittype.h     Mon Jun  9 10:49:20 2014
@@ -483,6 +483,11 @@
 bool unit_can_take_over(const struct unit *punit);
 bool utype_can_take_over(const struct unit_type *punittype);
 
+bool utype_can_freely_load(const struct unit_type *pcargotype,
+                           const struct unit_type *ptranstype);
+bool utype_can_freely_unload(const struct unit_type *pcargotype,
+                             const struct unit_type *ptranstype);
+
 /* Functions to operate on various flag and roles. */
 typedef bool (*role_unit_callback)(struct unit_type *ptype, void *data);
 


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to