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