Author: sveinung
Date: Fri Oct 28 15:15:58 2016
New Revision: 34276

URL: http://svn.gna.org/viewcvs/freeciv?rev=34276&view=rev
Log:
Reusable action auto performer's rs conversion.

Action auto performers aren't fully exposed in the ruleset because their
semantic still isn't set in stone (see patch #6638). Make the code "missing
unit upkeep" uses to convert between action auto performers (in Freeciv's
memory) and regular settings (in the ruleset) reusable.

See patch #7885

Modified:
    trunk/server/ruleset.c
    trunk/tools/ruleutil/rulesave.c

Modified: trunk/server/ruleset.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/server/ruleset.c?rev=34276&r1=34275&r2=34276&view=diff
==============================================================================
--- trunk/server/ruleset.c      (original)
+++ trunk/server/ruleset.c      Fri Oct 28 15:15:58 2016
@@ -5003,6 +5003,87 @@
 }
 
 /**************************************************************************
+  Load a list of unit type flags that must be absent from the actor unit
+  if an action auto performer should be triggered into an action auto
+  performer.
+**************************************************************************/
+static bool load_action_auto_uflag_block(struct section_file *file,
+                                         struct action_auto_perf *auto_perf,
+                                         const char *uflags_path,
+                                         const char *filename)
+{
+  /* Add each listed protected unit type flag as a !present
+   * requirement. */
+  if (secfile_entry_lookup(file, "%s", uflags_path)) {
+    enum unit_type_flag_id *protecor_flag;
+    size_t psize;
+    int i;
+
+    protecor_flag =
+        secfile_lookup_enum_vec(file, &psize, unit_type_flag_id,
+                                "%s", uflags_path);
+
+    if (!protecor_flag) {
+      /* Entity exists but couldn't read it. */
+      ruleset_error(LOG_ERROR,
+                    "\"%s\": %s: bad unit type flag list.",
+                    filename, uflags_path);
+
+      return FALSE;
+    }
+
+    for (i = 0; i < psize; i++) {
+      requirement_vector_append(&auto_perf->reqs,
+                                req_from_values(VUT_UTFLAG,
+                                                REQ_RANGE_LOCAL,
+                                                FALSE, FALSE, TRUE,
+                                                protecor_flag[i]));
+    }
+
+    free(protecor_flag);
+  }
+
+  return TRUE;
+}
+
+/**************************************************************************
+  Load the list of actions an action auto performer should try. The
+  actions will be tried in the given order.
+**************************************************************************/
+static bool load_action_auto_actions(struct section_file *file,
+                                     struct action_auto_perf *auto_perf,
+                                     const char *actions_path,
+                                     const char *filename)
+{
+  /* Read the alternative actions. */
+  if (secfile_entry_lookup(file, "%s", actions_path)) {
+    enum gen_action *unit_acts;
+    size_t asize;
+    int i;
+
+    unit_acts = secfile_lookup_enum_vec(file, &asize, gen_action,
+                                        "%s", actions_path);
+
+    if (!unit_acts) {
+      /* Entity exists but couldn't read it. */
+      ruleset_error(LOG_ERROR,
+                    "\"%s\": %s: bad action list",
+                    filename, actions_path);
+
+      return FALSE;
+    }
+
+    for (i = 0; i < asize; i++) {
+      auto_perf->alternatives[i] = unit_acts[i];
+    }
+
+    free(unit_acts);
+  }
+
+  return TRUE;
+}
+
+/**************************************************************************
   Load missing unit upkeep ruleset settings as action auto performers.
 **************************************************************************/
 static bool load_muuk_as_action_auto(struct section_file *file,
@@ -5010,68 +5091,18 @@
                                      const char *item,
                                      const char *filename)
 {
-  /* Add each listed protected unit type flag as a !present
-   * requirement. */
-  if (secfile_entry_lookup(file,
-                           "missing_unit_upkeep.%s_protected", item)) {
-    enum unit_type_flag_id *protecor_flag;
-    size_t psize;
-    int i;
-
-    protecor_flag =
-        secfile_lookup_enum_vec(file, &psize, unit_type_flag_id,
-                                "missing_unit_upkeep.%s_protected", item);
-
-    if (!protecor_flag) {
-      /* Entity exists but couldn't read it. */
-      ruleset_error(LOG_ERROR,
-                    "\"%s\": missing_unit_upkeep.%s_protected: bad unit "
-                    " type flag list.",
-                    filename, item);
-
-      return FALSE;
-    }
-
-    for (i = 0; i < psize; i++) {
-      requirement_vector_append(&auto_perf->reqs,
-                                req_from_values(VUT_UTFLAG,
-                                                REQ_RANGE_LOCAL,
-                                                FALSE, FALSE, TRUE,
-                                                protecor_flag[i]));
-    }
-
-    free(protecor_flag);
-  }
-
-  /* Read the alternative actions. */
-  if (secfile_entry_lookup(file,
-                           "missing_unit_upkeep.%s_unit_act", item)) {
-    enum gen_action *unit_acts;
-    size_t asize;
-    int i;
-
-    unit_acts =
-        secfile_lookup_enum_vec(file, &asize, gen_action,
-                                "missing_unit_upkeep.%s_unit_act", item);
-
-    if (!unit_acts) {
-      /* Entity exists but couldn't read it. */
-      ruleset_error(LOG_ERROR,
-                    "\"%s\": missing_unit_upkeep.%s_unit_act: bad action "
-                    "list",
-                    filename, item);
-
-      return FALSE;
-    }
-
-    for (i = 0; i < asize; i++) {
-      auto_perf->alternatives[i] = unit_acts[i];
-    }
-
-    free(unit_acts);
-  }
-
-  return TRUE;
+  char uflags_path[100];
+  char action_path[100];
+
+  fc_snprintf(uflags_path, sizeof(uflags_path),
+              "missing_unit_upkeep.%s_protected", item);
+  fc_snprintf(action_path, sizeof(action_path),
+              "missing_unit_upkeep.%s_unit_act", item);
+
+  return (load_action_auto_uflag_block(file, auto_perf, uflags_path,
+                                       filename)
+          && load_action_auto_actions(file, auto_perf, action_path,
+                                      filename));
 }
 
 /**************************************************************************

Modified: trunk/tools/ruleutil/rulesave.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/tools/ruleutil/rulesave.c?rev=34276&r1=34275&r2=34276&view=diff
==============================================================================
--- trunk/tools/ruleutil/rulesave.c     (original)
+++ trunk/tools/ruleutil/rulesave.c     Fri Oct 28 15:15:58 2016
@@ -505,15 +505,63 @@
 }
 
 /**************************************************************************
-  Save the action a unit should perform when its missing food, gold or
-  shield upkeep. Save as regular settings since the Action Auto Perform
-  rules system isn't ready to be exposed to the ruleset yet.
-**************************************************************************/
-static bool save_hidden_action_auto(struct section_file *sfile,
-                                    const int aap,
-                                    const char *item)
+  Save an action auto performer's !present utype reqs as a regular setting.
+  This is done because the Action Auto Perform rules system isn't ready to
+  be exposed to the ruleset yet. The setting is a list of utype flags that
+  prevents the auto action performer.
+**************************************************************************/
+static bool save_action_auto_uflag_block(struct section_file *sfile,
+                                         const int aap,
+                                         const char *uflags_path,
+                                         bool (*unexpected_req)(
+                                           const struct requirement *preq))
 {
   enum unit_type_flag_id protecor_flag[MAX_NUM_USER_UNIT_FLAGS];
+  size_t i;
+  size_t ret;
+
+  const struct action_auto_perf *auto_perf =
+      action_auto_perf_by_number(aap);
+
+  i = 0;
+  requirement_vector_iterate(&auto_perf->reqs, req) {
+    fc_assert(req->range == REQ_RANGE_LOCAL);
+
+    if (req->source.kind == VUT_UTFLAG) {
+      fc_assert(!req->present);
+
+      protecor_flag[i++] = req->source.value.unitflag;
+    } else if (unexpected_req(req)) {
+      log_error("Can't handle action auto performer requirement %s",
+                req_to_fstring(req));
+
+      return FALSE;
+    }
+  } requirement_vector_iterate_end;
+
+  ret = secfile_insert_enum_vec(sfile, &protecor_flag, i,
+                                unit_type_flag_id,
+                                "%s", uflags_path);
+
+  if (ret != i) {
+    log_error("%s: didn't save all unit type flags.", uflags_path);
+
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**************************************************************************
+  Save an action auto performer's action list as a regular setting. This
+  is done because the Action Auto Perform rules system isn't ready to be
+  exposed to the ruleset yet. The setting is a list of actions in the
+  order they should be tried.
+**************************************************************************/
+static bool save_action_auto_actions(struct section_file *sfile,
+                                         const int aap,
+                                         const char *actions_path)
+{
   enum gen_action unit_acts[ACTION_COUNT];
   size_t i;
   size_t ret;
@@ -522,31 +570,6 @@
       action_auto_perf_by_number(aap);
 
   i = 0;
-  requirement_vector_iterate(&auto_perf->reqs, req) {
-    fc_assert(req->range == REQ_RANGE_LOCAL);
-
-    if (req->source.kind == VUT_UTFLAG) {
-      fc_assert(!req->present);
-
-      protecor_flag[i++] = req->source.value.unitflag;
-    } else if (!(req->source.kind == VUT_OTYPE && req->present)) {
-      log_error("Can't handle action auto performer requirement %s",
-                req_to_fstring(req));
-
-      return FALSE;
-    }
-  } requirement_vector_iterate_end;
-
-  ret = secfile_insert_enum_vec(sfile, &protecor_flag, i,
-                                unit_type_flag_id,
-                                "missing_unit_upkeep.%s_protected", item);
-
-  if (ret != i) {
-    log_error("Didn't save all unit flags protected from upkeep killing");
-
-    return FALSE;
-  }
-
   for (i = 0;
        i < ACTION_COUNT && auto_perf->alternatives[i] != ACTION_COUNT;
        i++) {
@@ -554,15 +577,46 @@
   }
 
   ret = secfile_insert_enum_vec(sfile, &unit_acts, i, gen_action,
-                                "missing_unit_upkeep.%s_unit_act", item);
+                                "%s", actions_path);
 
   if (ret != i) {
-    log_error("Didn't save all upkeep failure actions");
+    log_error("%s: didn't save all actions.", actions_path);
 
     return FALSE;
   }
 
   return TRUE;
+}
+
+/**************************************************************************
+  Missing unit upkeep should only contain output type and absence of
+  blocking unit type flag requirements.
+**************************************************************************/
+static bool unexpected_non_otype(const struct requirement *req)
+{
+  return !(req->source.kind == VUT_OTYPE && req->present);
+}
+
+/**************************************************************************
+  Save the action a unit should perform when its missing food, gold or
+  shield upkeep. Save as regular settings since the Action Auto Perform
+  rules system isn't ready to be exposed to the ruleset yet.
+**************************************************************************/
+static bool save_muuk_action_auto(struct section_file *sfile,
+                                  const int aap,
+                                  const char *item)
+{
+  char uflags_path[100];
+  char action_path[100];
+
+  fc_snprintf(uflags_path, sizeof(uflags_path),
+              "missing_unit_upkeep.%s_protected", item);
+  fc_snprintf(action_path, sizeof(action_path),
+              "missing_unit_upkeep.%s_unit_act", item);
+
+  return (save_action_auto_uflag_block(sfile, aap, uflags_path,
+                                       unexpected_non_otype)
+          && save_action_auto_actions(sfile, aap, action_path));
 }
 
 /**************************************************************************
@@ -652,22 +706,22 @@
                        "citizen.partisans_pct");
   }
 
-  save_hidden_action_auto(sfile, ACTION_AUTO_UPKEEP_FOOD,
-                          "food");
+  save_muuk_action_auto(sfile, ACTION_AUTO_UPKEEP_FOOD,
+                        "food");
   if (game.info.muuk_food_wipe != RS_DEFAULT_MUUK_FOOD_WIPE) {
     secfile_insert_bool(sfile, game.info.muuk_food_wipe,
                         "missing_unit_upkeep.food_wipe");
   }
 
-  save_hidden_action_auto(sfile, ACTION_AUTO_UPKEEP_GOLD,
-                          "gold");
+  save_muuk_action_auto(sfile, ACTION_AUTO_UPKEEP_GOLD,
+                        "gold");
   if (game.info.muuk_gold_wipe != RS_DEFAULT_MUUK_GOLD_WIPE) {
     secfile_insert_bool(sfile, game.info.muuk_gold_wipe,
                         "missing_unit_upkeep.gold_wipe");
   }
 
-  save_hidden_action_auto(sfile, ACTION_AUTO_UPKEEP_SHIELD,
-                          "shield");
+  save_muuk_action_auto(sfile, ACTION_AUTO_UPKEEP_SHIELD,
+                        "shield");
   if (game.info.muuk_shield_wipe != RS_DEFAULT_MUUK_SHIELD_WIPE) {
     secfile_insert_bool(sfile, game.info.muuk_shield_wipe,
                         "missing_unit_upkeep.shield_wipe");


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

Reply via email to