<URL: http://bugs.freeciv.org/Ticket/Display.html?id=39638 >
On 01/09/2007, Marko Lindqvist wrote>
>
> On 31/08/2007, Joan Creus wrote:
> >
> > Anyway, implementing an
> > and-list and an or-list shouldn't be too hard, and it pays off with more
> > natural sentences.
>
> Attached patch does that. It also makes help a bit more complete and
> fixes some logical errors.
TRUNK version.
- ML
diff -Nurd -X.diff_ignore freeciv/client/helpdata.c freeciv/client/helpdata.c
--- freeciv/client/helpdata.c 2007-08-31 11:51:59.000000000 +0300
+++ freeciv/client/helpdata.c 2007-09-01 11:35:54.000000000 +0300
@@ -1249,27 +1249,112 @@
effect_list_iterate(get_req_source_effects(&source), peffect) {
Output_type_id output_type = O_LAST;
struct unit_class *unitclass = NULL;
+ struct unit_type *unittype = NULL;
enum unit_flag_id unitflag = F_LAST;
- const char *output = "All";
+ struct astring outputs_or = ASTRING_INIT;
+ struct astring outputs_and = ASTRING_INIT;
+ bool extra_reqs = FALSE;
+
+ astr_clear(&outputs_or);
+ astr_clear(&outputs_and);
/* Grab output type, if there is one */
requirement_list_iterate(peffect->reqs, preq) {
switch (preq->source.kind) {
- case VUT_OTYPE:
- output_type = preq->source.value.outputtype;
- output = get_output_name(output_type);
- break;
- case VUT_UCLASS:
- unitclass = preq->source.value.uclass;
- break;
- case VUT_UTFLAG:
- unitflag = preq->source.value.unitflag;
- break;
- default:
- break;
+ case VUT_OTYPE:
+ if (output_type == O_LAST) {
+ /* We should never have multiple outputtype requirements
+ * in one list in the first place (it simply makes no sense,
+ * output cannot be of multiple types)
+ * Ruleset loading code should check against that. */
+ const char *oname;
+
+ output_type = preq->source.value.outputtype;
+ oname = get_output_name(output_type);
+ astr_add(&outputs_or, oname);
+ astr_add(&outputs_and, oname);
+ }
+ break;
+ case VUT_UCLASS:
+ if (unitclass == NULL) {
+ unitclass = preq->source.value.uclass;
+ }
+ break;
+ case VUT_UTYPE:
+ if (unittype == NULL) {
+ unittype = preq->source.value.utype;
+ }
+ break;
+ case VUT_UTFLAG:
+ if (unitflag == F_LAST) {
+ /* FIXME: We should list all the unit flag requirements,
+ * not only first one. */
+ unitflag = preq->source.value.unitflag;
+ }
+ break;
+ case VUT_GOVERNMENT:
+ /* This is government we are generating helptext for.
+ * ...or if not, it's ruleset bug that should never make it
+ * this far. Fix ruleset loading code. */
+ break;
+ default:
+ extra_reqs = TRUE;
+ break;
};
} requirement_list_iterate_end;
+ if (!extra_reqs) {
+ /* Only list effects that have no special requirements. */
+
+ if (output_type == O_LAST) {
+ /* There was no outputtype requirement. Effect is active for all
+ * output types. Generate lists for that. */
+ const char *prev = NULL;
+ const char *prev2 = NULL;
+ bool harvested_only = TRUE; /* Consider only output types from fields */
+
+ if (peffect->type == EFT_UPKEEP_FACTOR
+ || peffect->type == EFT_UNIT_UPKEEP_FREE_PER_CITY
+ || peffect->type == EFT_OUTPUT_BONUS
+ || peffect->type == EFT_OUTPUT_BONUS_2) {
+ /* Effect can use or require any kind of output */
+ harvested_only = FALSE;
+ }
+
+ output_type_iterate(ot) {
+ struct output_type *pot = get_output_type(ot);
+
+ if (!harvested_only || pot->harvested) {
+ if (prev2 != NULL) {
+ astr_add(&outputs_or, prev2);
+ astr_add(&outputs_or, ", ");
+ astr_add(&outputs_and, prev2);
+ astr_add(&outputs_and, ", ");
+ }
+ prev2 = prev;
+ prev = _(pot->name);
+ }
+ } output_type_iterate_end;
+ if (prev2 != NULL) {
+ astr_add(&outputs_or, prev2);
+ /* TRANS: List of possible output types has this between
+ * last two elements */
+ astr_add(&outputs_or, Q_("?outputlist: or "));
+ astr_add(&outputs_and, prev2);
+ /* TRANS: List of possible output types has this between
+ * last two elements */
+ astr_add(&outputs_and, Q_("?outputlist: and "));
+ }
+ if (prev != NULL) {
+ astr_add(&outputs_or, prev);
+ astr_add(&outputs_and, prev);
+ } else {
+ /* TRANS: Empty output type list, should never happen. */
+ astr_add(&outputs_or, Q_("?outputlist: Nothing "));
+ astr_add(&outputs_and, Q_("?outputlist: Nothing "));
+ }
+ }
+
switch (peffect->type) {
case EFT_UNHAPPY_FACTOR:
if (peffect->value == 1) {
@@ -1289,22 +1374,35 @@
break;
case EFT_UPKEEP_FACTOR:
if (peffect->value > 1 && output_type != O_LAST) {
- sprintf(buf + strlen(buf), _("* You pay %d times normal %s "
- "upkeep for your units.\n"), peffect->value, output);
+ /* TRANS: %s is always only one output type, never list */
+ sprintf(buf + strlen(buf),
+ _("* You pay %d times normal %s upkeep for your units.\n"),
+ peffect->value, outputs_and.str);
} else if (peffect->value > 1) {
sprintf(buf + strlen(buf), _("* You pay %d times normal "
"upkeep for your units.\n"), peffect->value);
+ } else if (peffect->value == 0 && output_type != O_LAST) {
+ /* TRANS: %s is output type */
+ sprintf(buf + strlen(buf),
+ _("* You pay no %s upkeep for your units.\n"),
+ outputs_and.str);
+ } else if (peffect->value == 0) {
+ /* TRANS: No upkeep of any type */
+ sprintf(buf + strlen(buf),
+ _("* You pay no upkeep for your units.\n"));
}
break;
case EFT_UNIT_UPKEEP_FREE_PER_CITY:
if (output_type != O_LAST) {
- /* TRANS: %s is the output type, like 'shields' or 'gold'. There
+ /* TRANS: %s is the output type, like 'shield' or 'gold'. There
* is currently no way to control the singular/plural version of
* this. */
sprintf(buf + strlen(buf), _("* Each of your cities will avoid "
"paying %d %s towards unit upkeep.\n"), peffect->value,
- output);
+ outputs_and.str);
} else {
+ /* TRANS: Amount is subtracted from upkeep cost in each upkeep
+ * type. */
sprintf(buf + strlen(buf), _("* Each of your cities will avoid "
"paying %d towards unit upkeep.\n"), peffect->value);
}
@@ -1386,9 +1484,17 @@
sprintf(buf + strlen(buf), _("* Has no unhappy citizens.\n"));
break;
case EFT_VETERAN_BUILD:
+ /* FIXME: There could be both class and flag requirement.
+ * meaning that only some units from class are affected.
+ * Should class related string, type related strings and
+ * flag related string to be at least qualified to allow
+ * different translations? */
if (unitclass) {
sprintf(buf + strlen(buf), _("* Veteran %s units.\n"),
uclass_name_translation(unitclass));
+ } else if (unittype != NULL) {
+ sprintf(buf + strlen(buf), _("* Veteran %s units.\n"),
+ utype_name_translation(unittype));
} else if (unitflag != F_LAST) {
sprintf(buf + strlen(buf), _("* Veteran %s units.\n"),
unit_flag_rule_name(unitflag));
@@ -1397,46 +1503,67 @@
}
break;
case EFT_OUTPUT_PENALTY_TILE:
+ /* TRANS: %s is list of output types, with 'or' */
sprintf(buf + strlen(buf), _("* Each worked tile that gives more "
"than %d %s will suffer a -1 penalty when not "
- "celebrating.\n"), peffect->value, output);
+ "celebrating.\n"), peffect->value, outputs_or.str);
break;
case EFT_OUTPUT_INC_TILE_CELEBRATE:
+ /* TRANS: %s is list of output types, with 'or' */
sprintf(buf + strlen(buf), _("* Each worked tile with at least 1 "
- "%s will yield %d additional %s when celebrating.\n"),
- output, peffect->value, output);
+ "%s will yield %d more it when celebrating.\n"),
+ outputs_or.str, peffect->value);
break;
case EFT_OUTPUT_INC_TILE:
+ /* TRANS: %s is list of output types, with 'or' */
sprintf(buf + strlen(buf), _("* Each worked tile with at least 1 "
- "%s will yield %d additional %s.\n"), output,
- peffect->value, output);
+ "%s will yield %d more it.\n"), outputs_or.str,
+ peffect->value);
+ break;
+ case EFT_OUTPUT_BONUS:
+ case EFT_OUTPUT_BONUS_2:
+ /* TRANS: %s is list of output types, with 'and' */
+ sprintf(buf + strlen(buf), _("* %s production is increased %d%%.\n"),
+ outputs_and.str, peffect->value);
break;
case EFT_OUTPUT_WASTE:
if (peffect->value > 30) {
+ /* TRANS: %s is list of output types, with 'and' */
sprintf(buf + strlen(buf), _("* %s production will suffer "
- "massive waste.\n"), output);
+ "massive waste.\n"), outputs_and.str);
} else if (peffect->value >= 15) {
+ /* TRANS: %s is list of output types, with 'and' */
sprintf(buf + strlen(buf), _("* %s production will suffer "
- "some waste.\n"), output);
+ "some waste.\n"), outputs_and.str);
} else {
+ /* TRANS: %s is list of output types, with 'and' */
sprintf(buf + strlen(buf), _("* %s production will suffer "
- "a small amount of waste.\n"), output);
+ "a small amount of waste.\n"), outputs_and.str);
}
break;
case EFT_OUTPUT_WASTE_BY_DISTANCE:
if (peffect->value >= 3) {
+ /* TRANS: %s is list of output types, with 'and' */
sprintf(buf + strlen(buf), _("* %s waste will increase quickly "
- "with distance from capital.\n"), output);
+ "with distance from capital.\n"), outputs_and.str);
} else if (peffect->value == 2) {
+ /* TRANS: %s is list of output types, with 'and' */
sprintf(buf + strlen(buf), _("* %s waste will increase "
- "with distance from capital.\n"), output);
+ "with distance from capital.\n"), outputs_and.str);
} else {
+ /* TRANS: %s is list of output types, with 'and' */
sprintf(buf + strlen(buf), _("* %s waste will increase slowly "
- "with distance from capital.\n"), output);
+ "with distance from capital.\n"), outputs_and.str);
}
default:
break;
}
+
+ }
+
+ astr_clear(&outputs_or);
+ astr_clear(&outputs_and);
+
} effect_list_iterate_end;
unit_type_iterate(utype) {
diff -Nurd -X.diff_ignore freeciv/common/city.c freeciv/common/city.c
--- freeciv/common/city.c 2007-08-13 20:51:03.000000000 +0300
+++ freeciv/common/city.c 2007-09-01 11:25:28.000000000 +0300
@@ -52,12 +52,12 @@
* they're just an easy way to access information about each output type. */
const Output_type_id num_output_types = O_LAST;
struct output_type output_types[O_LAST] = {
- {O_FOOD, N_("Food"), "food", UNHAPPY_PENALTY_SURPLUS},
- {O_SHIELD, N_("Shield"), "shield", UNHAPPY_PENALTY_SURPLUS},
- {O_TRADE, N_("Trade"), "trade", UNHAPPY_PENALTY_NONE},
- {O_GOLD, N_("Gold"), "gold", UNHAPPY_PENALTY_ALL_PRODUCTION},
- {O_LUXURY, N_("Luxury"), "luxury", UNHAPPY_PENALTY_NONE},
- {O_SCIENCE, N_("Science"), "science", UNHAPPY_PENALTY_ALL_PRODUCTION}
+ {O_FOOD, N_("Food"), "food", TRUE, UNHAPPY_PENALTY_SURPLUS},
+ {O_SHIELD, N_("Shield"), "shield", TRUE, UNHAPPY_PENALTY_SURPLUS},
+ {O_TRADE, N_("Trade"), "trade", TRUE, UNHAPPY_PENALTY_NONE},
+ {O_GOLD, N_("Gold"), "gold", FALSE, UNHAPPY_PENALTY_ALL_PRODUCTION},
+ {O_LUXURY, N_("Luxury"), "luxury", FALSE, UNHAPPY_PENALTY_NONE},
+ {O_SCIENCE, N_("Science"), "science", FALSE, UNHAPPY_PENALTY_ALL_PRODUCTION}
};
/**************************************************************************
diff -Nurd -X.diff_ignore freeciv/common/city.h freeciv/common/city.h
--- freeciv/common/city.h 2007-08-30 18:05:19.000000000 +0300
+++ freeciv/common/city.h 2007-09-01 11:25:28.000000000 +0300
@@ -144,7 +144,8 @@
struct output_type {
int index;
const char *name; /* Untranslated name */
- const char *id; /* Identifier string (for rulesets, etc.) */
+ const char *id; /* Identifier string (for rulesets, etc.) */
+ bool harvested; /* Is this output type gathered by city workers? */
enum output_unhappy_penalty unhappy_penalty;
};
_______________________________________________
Freeciv-dev mailing list
[email protected]
https://mail.gna.org/listinfo/freeciv-dev