<URL: http://bugs.freeciv.org/Ticket/Display.html?id=37218 >
This patch adds requirement vector for bases. This replaces tech flags TF_FORTRESS and TF_AIRBASE. - ML
diff -Nurd -X.diff_ignore freeciv/client/helpdata.c freeciv/client/helpdata.c --- freeciv/client/helpdata.c 2007-02-26 14:16:19.000000000 +0200 +++ freeciv/client/helpdata.c 2007-03-01 00:48:13.000000000 +0200 @@ -869,21 +869,8 @@ } /* Fortress. */ - switch (techs_with_flag_string(TF_FORTRESS, buf2, sizeof(buf2))) { - case 0: - sprintf(buf + strlen(buf), _("* Can build fortresses.\n")); - break; - case 1: - sprintf(buf + strlen(buf), - _("* Can build fortresses (if %s is known).\n"), buf2); - break; - default: - sprintf(buf + strlen(buf), - _("* Can build fortresses (if any of the following are " - "known: %s).\n"), buf2); - break; - } - + sprintf(buf + strlen(buf), _("* Can build fortresses.\n")); + /* Pollution, fallout. */ sprintf(buf + strlen(buf), _("* Can clean pollution from tiles.\n")); sprintf(buf + strlen(buf), @@ -1134,22 +1121,6 @@ free((void *) units_str); } - if (tech_flag(i, TF_FORTRESS)) { - const char *units_str = get_units_with_flag_string(F_SETTLERS); - sprintf(buf + strlen(buf), _("* Allows %s to build fortresses.\n"), - units_str); - free((void *) units_str); - } - - if (tech_flag(i, TF_AIRBASE)) { - const char *units_str = get_units_with_flag_string(F_AIRBASE); - if (units_str) { - sprintf(buf + strlen(buf), _("* Allows %s to build airbases.\n"), - units_str); - free((void *) units_str); - } - } - if (tech_flag(i, TF_RAILROAD)) { const char *units_str = get_units_with_flag_string(F_SETTLERS); sprintf(buf + strlen(buf), diff -Nurd -X.diff_ignore freeciv/client/packhand.c freeciv/client/packhand.c --- freeciv/client/packhand.c 2007-02-26 14:16:18.000000000 +0200 +++ freeciv/client/packhand.c 2007-03-01 00:22:48.000000000 +0200 @@ -2447,6 +2447,7 @@ void handle_ruleset_base(struct packet_ruleset_base *p) { struct base_type *pbase = base_type_get_by_id(p->id); + int i; if (!pbase) { freelog(LOG_ERROR, @@ -2458,6 +2459,11 @@ sz_strlcpy(pbase->name_orig, p->name); pbase->name = Q_(pbase->name_orig); + for (i = 0; i < p->reqs_count; i++) { + requirement_vector_append(&pbase->reqs, &p->reqs[i]); + } + assert(pbase->reqs.size == p->reqs_count); + pbase->flags = p->flags; } diff -Nurd -X.diff_ignore freeciv/common/base.c freeciv/common/base.c --- freeciv/common/base.c 2007-02-28 23:02:37.000000000 +0200 +++ freeciv/common/base.c 2007-03-01 00:44:38.000000000 +0200 @@ -18,6 +18,8 @@ #include <assert.h> #include "base.h" +#include "tile.h" +#include "unit.h" static struct base_type base_types[BASE_LAST]; @@ -43,6 +45,27 @@ return pbase->name; } +/************************************************************************** + Can unit build base to given tile? +**************************************************************************/ +bool can_build_base(const struct unit *punit, const struct base_type *pbase, + const struct tile *ptile) +{ + if ((pbase->id == BASE_FORTRESS && !unit_flag(punit, F_SETTLERS)) || + (pbase->id == BASE_AIRBASE && !unit_flag(punit, F_AIRBASE))) { + /* This unit cannot build this kind of base */ + return FALSE; + } + + if (tile_get_city(ptile)) { + /* Bases cannot be built inside cities */ + return FALSE; + } + + return are_reqs_active(unit_owner(punit), NULL, NULL, ptile, + unit_type(punit), NULL, NULL, &pbase->reqs); +} + /**************************************************************************** Determine base type from specials. Returns NULL if there is no base ****************************************************************************/ @@ -96,5 +119,6 @@ for (i = 0; i < ARRAY_SIZE(base_types); i++) { base_types[i].id = i; + requirement_vector_init(&base_types[i].reqs); } } diff -Nurd -X.diff_ignore freeciv/common/base.h freeciv/common/base.h --- freeciv/common/base.h 2007-02-28 23:02:38.000000000 +0200 +++ freeciv/common/base.h 2007-03-01 00:39:01.000000000 +0200 @@ -14,6 +14,7 @@ #define FC__BASE_H #include "fc_types.h" +#include "requirements.h" #include "terrain.h" enum base_type_id { BASE_FORTRESS = 0, BASE_AIRBASE, BASE_LAST }; @@ -41,12 +42,16 @@ const char *name; char name_orig[MAX_LEN_NAME]; int id; + struct requirement_vector reqs; bv_base_flags flags; }; bool base_flag(const struct base_type *pbase, enum base_flag_id flag); const char *base_name(const struct base_type *pbase); +bool can_build_base(const struct unit *punit, const struct base_type *pbase, + const struct tile *ptile); + struct base_type *base_type_get_from_special(bv_special spe); enum base_flag_id base_flag_from_str(const char *s); diff -Nurd -X.diff_ignore freeciv/common/packets.def freeciv/common/packets.def --- freeciv/common/packets.def 2007-02-26 14:16:16.000000000 +0200 +++ freeciv/common/packets.def 2007-03-01 00:21:40.000000000 +0200 @@ -1270,6 +1270,8 @@ PACKET_RULESET_BASE=120;sc,lsend UINT8 id; STRING name[MAX_LEN_NAME]; + UINT8 reqs_count; + REQUIREMENT reqs[MAX_NUM_REQS:reqs_count]; BV_BASE_FLAGS flags; end diff -Nurd -X.diff_ignore freeciv/common/tech.c freeciv/common/tech.c --- freeciv/common/tech.c 2007-02-26 14:16:16.000000000 +0200 +++ freeciv/common/tech.c 2007-03-01 00:34:28.000000000 +0200 @@ -40,9 +40,9 @@ static double techcoststyle1[A_LAST]; static const char *flag_names[] = { - "Bonus_Tech", "Bridge", "Railroad", "Fortress", + "Bonus_Tech", "Bridge", "Railroad", "Population_Pollution_Inc", - "Airbase", "Farmland", + "Farmland", "Build_Airborne" }; /* Note that these strings must correspond with the enums in tech_flag_id, diff -Nurd -X.diff_ignore freeciv/common/tech.h freeciv/common/tech.h --- freeciv/common/tech.h 2007-02-26 14:16:16.000000000 +0200 +++ freeciv/common/tech.h 2007-03-01 00:34:05.000000000 +0200 @@ -55,9 +55,7 @@ TF_BONUS_TECH, /* player gets extra tech if rearched first */ TF_BRIDGE, /* "Settler" unit types can build bridges over rivers */ TF_RAILROAD, /* "Settler" unit types can build rail roads */ - TF_FORTRESS, /* "Settler" unit types can build fortress */ TF_POPULATION_POLLUTION_INC, /* Increase the pollution factor created by popultaion by one */ - TF_AIRBASE, /* "Airbase" unit types can build Airbases */ TF_FARMLAND, /* "Settler" unit types can build farmland */ TF_BUILD_AIRBORNE, /* Player can build air units */ TF_LAST diff -Nurd -X.diff_ignore freeciv/common/unit.c freeciv/common/unit.c --- freeciv/common/unit.c 2007-02-28 23:02:38.000000000 +0200 +++ freeciv/common/unit.c 2007-03-01 00:43:50.000000000 +0200 @@ -831,16 +831,13 @@ case ACTIVITY_FORTRESS: pbase = tile_get_base(ptile); - return (unit_flag(punit, F_SETTLERS) - && !tile_get_city(ptile) - && player_knows_techs_with_flag(pplayer, TF_FORTRESS) + return (can_build_base(punit, base_type_get_by_id(BASE_FORTRESS), ptile) && (pbase == NULL || pbase->id != BASE_FORTRESS) && !is_ocean(ptile->terrain)); case ACTIVITY_AIRBASE: pbase = tile_get_base(ptile); - return (unit_flag(punit, F_AIRBASE) - && player_knows_techs_with_flag(pplayer, TF_AIRBASE) + return (can_build_base(punit, base_type_get_by_id(BASE_AIRBASE), ptile) && (pbase == NULL || pbase->id != BASE_AIRBASE) && !is_ocean(ptile->terrain)); diff -Nurd -X.diff_ignore freeciv/data/civ1/techs.ruleset freeciv/data/civ1/techs.ruleset --- freeciv/data/civ1/techs.ruleset 2007-01-29 01:04:05.000000000 +0200 +++ freeciv/data/civ1/techs.ruleset 2007-03-01 00:46:10.000000000 +0200 @@ -170,7 +170,7 @@ name = _("Construction") req1 = "Masonry" req2 = "Currency" -flags = "Fortress" +flags = "" graphic = "a.construction" graphic_alt = "-" diff -Nurd -X.diff_ignore freeciv/data/civ1/terrain.ruleset freeciv/data/civ1/terrain.ruleset --- freeciv/data/civ1/terrain.ruleset 2007-01-29 01:04:05.000000000 +0200 +++ freeciv/data/civ1/terrain.ruleset 2007-03-01 00:47:11.000000000 +0200 @@ -597,6 +597,8 @@ ; fortress and airbase. ; ; name = Name of the base type. +; reqs = requirements to build the base (see effects.ruleset +; and README.effects for help on requirements) ; flags ; - "NoAggressive" = Units inside are not considered aggressive ; - "DefenseBonus" = Units inside gain defense bonus @@ -611,10 +613,18 @@ [fortress] name = _("Fortress") +reqs = + { "type", "name", "range" + "Tech", "Construction", "Player" + } flags = "NoAggressive", "DefenseBonus", "Watchtower", "ClaimTerritory", "NoStackDeath", "DiplomatDefense" [airbase] name = _("Airbase") +reqs = + { "type", "name", "range" + "Tech", "Never", "Player" + } flags = "NoStackDeath", "DiplomatDefense", "Refuel", "NoHPLoss", "AttackUnreachable", "ParadropFrom" diff -Nurd -X.diff_ignore freeciv/data/civ2/techs.ruleset freeciv/data/civ2/techs.ruleset --- freeciv/data/civ2/techs.ruleset 2007-02-26 14:15:35.000000000 +0200 +++ freeciv/data/civ2/techs.ruleset 2007-03-01 00:46:00.000000000 +0200 @@ -187,7 +187,7 @@ name = _("Construction") req1 = "Masonry" req2 = "Currency" -flags = "Fortress" +flags = "" graphic = "a.construction" graphic_alt = "-" @@ -560,7 +560,7 @@ name = _("Radio") req1 = "Flight" req2 = "Electricity" -flags = "Airbase" +flags = "" graphic = "a.radio" graphic_alt = "-" diff -Nurd -X.diff_ignore freeciv/data/civ2/terrain.ruleset freeciv/data/civ2/terrain.ruleset --- freeciv/data/civ2/terrain.ruleset 2007-01-29 01:04:06.000000000 +0200 +++ freeciv/data/civ2/terrain.ruleset 2007-03-01 00:47:36.000000000 +0200 @@ -689,6 +689,8 @@ ; fortress and airbase. ; ; name = Name of the base type. +; reqs = requirements to build the base (see effects.ruleset +; and README.effects for help on requirements) ; flags ; - "NoAggressive" = Units inside are not considered aggressive ; - "DefenseBonus" = Units inside gain defense bonus @@ -703,10 +705,18 @@ [fortress] name = _("Fortress") +reqs = + { "type", "name", "range" + "Tech", "Construction", "Player" + } flags = "NoAggressive", "DefenseBonus", "Watchtower", "ClaimTerritory", "NoStackDeath", "DiplomatDefense" [airbase] name = _("Airbase") +reqs = + { "type", "name", "range" + "Tech", "Radio", "Player" + } flags = "NoStackDeath", "DiplomatDefense", "Refuel", "NoHPLoss", "AttackUnreachable", "ParadropFrom" diff -Nurd -X.diff_ignore freeciv/data/default/techs.ruleset freeciv/data/default/techs.ruleset --- freeciv/data/default/techs.ruleset 2007-02-26 14:15:37.000000000 +0200 +++ freeciv/data/default/techs.ruleset 2007-03-01 00:45:25.000000000 +0200 @@ -45,10 +45,8 @@ ; "Bridge" = "Settler" unit types can build bridges over rivers ; "Railroad" = "Settler" unit types can build rail roads ; "Farmland" = "Settler" unit types can build farmland -; "Fortress" = "Settler" unit types can build fortress ; "Population_Pollution_Inc" = Increase the pollution factor created by ; popultaion by one -; "Airbase" = "Airbase" unit types can build Airbases ; "Build_Airborne" = from now on can build air units (for use by AI) [advance_advanced_flight] @@ -200,7 +198,7 @@ name = _("Construction") req1 = "Masonry" req2 = "Currency" -flags = "Fortress" +flags = "" graphic = "a.construction" graphic_alt = "-" @@ -565,7 +563,7 @@ name = _("Radio") req1 = "Flight" req2 = "Electricity" -flags = "Airbase" +flags = "" graphic = "a.radio" graphic_alt = "-" diff -Nurd -X.diff_ignore freeciv/data/default/terrain.ruleset freeciv/data/default/terrain.ruleset --- freeciv/data/default/terrain.ruleset 2007-02-12 15:27:42.000000000 +0200 +++ freeciv/data/default/terrain.ruleset 2007-03-01 00:19:02.000000000 +0200 @@ -756,6 +756,8 @@ ; fortress and airbase. ; ; name = Name of the base type. +; reqs = requirements to build the base (see effects.ruleset +; and README.effects for help on requirements) ; flags ; - "NoAggressive" = Units inside are not considered aggressive ; - "DefenseBonus" = Units inside gain defense bonus @@ -770,10 +772,18 @@ [fortress] name = _("Fortress") +reqs = + { "type", "name", "range" + "Tech", "Construction", "Player" + } flags = "NoAggressive", "DefenseBonus", "Watchtower", "ClaimTerritory", "NoStackDeath", "DiplomatDefense" [airbase] name = _("Airbase") +reqs = + { "type", "name", "range" + "Tech", "Radio", "Player" + } flags = "NoStackDeath", "DiplomatDefense", "Refuel", "NoHPLoss", "AttackUnreachable", "ParadropFrom" diff -Nurd -X.diff_ignore freeciv/server/ruleset.c freeciv/server/ruleset.c --- freeciv/server/ruleset.c 2007-02-28 23:02:37.000000000 +0200 +++ freeciv/server/ruleset.c 2007-03-01 00:21:11.000000000 +0200 @@ -1787,6 +1787,7 @@ char **slist; int j; char *section; + struct requirement_vector *reqs; pbase->name = Q_(pbase->name_orig); @@ -1795,9 +1796,12 @@ } else if (pbase->id == BASE_AIRBASE) { section = "airbase"; } else { - freelog(LOG_ERROR, "Unhandled base type in loas_ruleset_terrain()"); + freelog(LOG_ERROR, "Unhandled base type in load_ruleset_terrain()"); exit(EXIT_FAILURE); } + reqs = lookup_req_list(file, section, "reqs"); + requirement_vector_copy(&pbase->reqs, reqs); + slist = secfile_lookup_str_vec(file, &nval, "%s.flags", section); BV_CLR_ALL(pbase->flags); for (j = 0; j < nval; j++) { @@ -3051,8 +3055,17 @@ struct packet_ruleset_base packet; base_type_iterate(b) { + int j; + packet.id = b->id; sz_strlcpy(packet.name, b->name); + + j = 0; + requirement_vector_iterate(&b->reqs, preq) { + packet.reqs[j++] = *preq; + } requirement_vector_iterate_end; + packet.reqs_count = j; + packet.flags = b->flags; lsend_packet_ruleset_base(dest, &packet); diff -Nurd -X.diff_ignore freeciv/version.in freeciv/version.in --- freeciv/version.in 2007-02-26 14:16:19.000000000 +0200 +++ freeciv/version.in 2007-03-01 00:31:15.000000000 +0200 @@ -24,4 +24,4 @@ # - Avoid adding a new manditory capbility to the development branch for # as long as possible. We want to maintain network compatibility with # the stable branch for as long as possible. -FREECIV_NETWORK_CAPSTRING("+Freeciv.Devel.2007.Feb.17c") +FREECIV_NETWORK_CAPSTRING("+Freeciv.Devel.2007.Mar.01")
_______________________________________________ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev