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