[Freeciv-Dev] (PR#12659) requirements for governments
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12659 >
This patch changes governments to use requirements (instead of a single
tech_req). This means governments could in theory depend on the
presence of more than one tech, or on a wonder being present, etc.
The AI code is okay but only handles tech requirements.
The EFT_ANY_GOVERNMENT cheats a little since it no longer checks if the
target government is on our tech tree. I think this would have to be
written as a special case.
Only the default ruleset is updated.
I think this is ready to be committed.
-jason
Index: ai/aihand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aihand.c,v
retrieving revision 1.109
diff -u -r1.109 aihand.c
--- ai/aihand.c 21 Mar 2005 14:10:53 -0000 1.109
+++ ai/aihand.c 26 Mar 2005 06:59:55 -0000
@@ -289,7 +289,7 @@
TIMING_LOG(LOG_DEBUG, pplayer, "Finding best government");
government_iterate(gov) {
int val = 0;
- int dist;
+ int dist, i;
if (gov->index == game.government_when_anarchy) {
continue; /* pointless */
@@ -337,7 +337,16 @@
val += (val * bonus) / 100;
- dist = MAX(1, num_unknown_techs_for_goal(pplayer, gov->required_tech));
+ /* FIXME: handle reqs other than technologies. */
+ dist = 0;
+ for (i = 0; i < MAX_NUM_REQS; i++) {
+ struct requirement *req = gov->req + i;
+
+ if (req->source.type == REQ_TECH) {
+ dist += MAX(1, num_unknown_techs_for_goal(pplayer,
+ req->source.value.tech));
+ }
+ }
val = amortize(val, dist);
ai->government_want[gov->index] = val; /* Save want */
} government_iterate_end;
@@ -360,9 +369,21 @@
ai->goal.revolution = gov->index;
}
if (ai->government_want[gov->index] > ai->goal.govt.val) {
+ int i;
+
ai->goal.govt.idx = gov->index;
ai->goal.govt.val = ai->government_want[gov->index];
- ai->goal.govt.req = gov->required_tech;
+
+ /* FIXME: handle reqs other than technologies. */
+ ai->goal.govt.req = A_NONE;
+ for (i = 0; i < MAX_NUM_REQS; i++) {
+ struct requirement *req = gov->req + i;
+
+ if (req->source.type == REQ_TECH) {
+ ai->goal.govt.req = req->source.value.tech;
+ break;
+ }
+ }
}
} government_iterate_end;
/* Goodness of the ideal gov is calculated relative to the goodness of the
Index: client/helpdata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/helpdata.c,v
retrieving revision 1.96
diff -u -r1.96 helpdata.c
--- client/helpdata.c 14 Mar 2005 20:26:24 -0000 1.96
+++ client/helpdata.c 26 Mar 2005 06:59:55 -0000
@@ -150,6 +150,43 @@
}
/****************************************************************
+ Append text for the requirement. Something like
+
+ "Requires the Communism technology.\n\n"
+*****************************************************************/
+static void insert_requirement(struct requirement *req,
+ char *buf, size_t bufsz)
+{
+ switch (req->source.type) {
+ case REQ_NONE:
+ return;
+ case REQ_LAST:
+ break;
+ case REQ_TECH:
+ cat_snprintf(buf, bufsz, _("Requires the %s technology.\n\n"),
+ get_tech_name(game.player_ptr, req->source.value.tech));
+ return;
+ case REQ_GOV:
+ cat_snprintf(buf, bufsz, _("Requires the %s government.\n\n"),
+ get_government_name(req->source.value.gov));
+ return;
+ case REQ_BUILDING:
+ cat_snprintf(buf, bufsz, _("Requires the %s building.\n\n"),
+ get_improvement_name(req->source.value.building));
+ return;
+ case REQ_SPECIAL:
+ cat_snprintf(buf, bufsz, _("Requires the %s terrain special.\n\n"),
+ get_special_name(req->source.value.special));
+ return;
+ case REQ_TERRAIN:
+ cat_snprintf(buf, bufsz, _("Requires the %s terrain.\n\n"),
+ get_terrain_name(req->source.value.terrain));
+ return;
+ }
+ assert(0);
+}
+
+/****************************************************************
...
*****************************************************************/
static struct help_item *new_help_item(int type)
@@ -1033,9 +1070,15 @@
}
government_iterate(g) {
- if (g->required_tech == i) {
- sprintf(buf + strlen(buf), _("* Allows changing government to %s.\n"),
- g->name);
+ int j;
+
+ /* FIXME: this should tell the other requirements. */
+ for (j = 0; j < MAX_NUM_REQS; j++) {
+ if (g->req[j].source.type == REQ_TECH
+ && g->req[j].source.value.tech == i) {
+ sprintf(buf + strlen(buf), _("* Allows changing government to %s.\n"),
+ g->name);
+ }
}
} government_iterate_end;
if (tech_flag(i, TF_BONUS_TECH)) {
@@ -1162,6 +1205,8 @@
{
struct government *gov;
bool active_types[O_MAX];
+ int j;
+ const size_t bufsz = 64000; /* FIXME: should be passed in */
/* Try to guess which output types that are active in this
* game by checking if _any_ government uses it. */
@@ -1185,9 +1230,8 @@
if (gov->helptext[0] != '\0') {
sprintf(buf, "%s\n\n", _(gov->helptext));
}
- if (gov->required_tech != A_NONE) {
- sprintf(buf + strlen(buf), _("Requires the %s technology.\n\n"),
- advances[gov->required_tech].name);
+ for (j = 0; j < MAX_NUM_REQS; j++) {
+ insert_requirement(gov->req + j, buf, bufsz);
}
if (gov->max_rate < 100 && game.rgame.changable_tax) {
sprintf(buf + strlen(buf),
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.482
diff -u -r1.482 packhand.c
--- client/packhand.c 26 Mar 2005 05:59:13 -0000 1.482
+++ client/packhand.c 26 Mar 2005 06:59:56 -0000
@@ -2301,6 +2301,7 @@
void handle_ruleset_government(struct packet_ruleset_government *p)
{
struct government *gov;
+ int j;
if (p->id < 0 || p->id >= game.government_count) {
freelog(LOG_ERROR,
@@ -2312,7 +2313,11 @@
gov->index = p->id;
- gov->required_tech = p->required_tech;
+ for (j = 0; j < MAX_NUM_REQS; j++) {
+ gov->req[j] = req_from_values(p->req_type[j], p->req_range[j],
+ p->req_survives[j], p->req_value[j]);
+ }
+
gov->max_rate = p->max_rate;
gov->civil_war = p->civil_war;
gov->martial_law_max = p->martial_law_max;
Index: common/government.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/government.c,v
retrieving revision 1.49
diff -u -r1.49 government.c
--- common/government.c 22 Jan 2005 21:12:10 -0000 1.49
+++ common/government.c 26 Mar 2005 06:59:56 -0000
@@ -193,21 +193,20 @@
***************************************************************/
bool can_change_to_government(struct player *pplayer, int government)
{
- int req;
+ struct government *gov = &governments[government];
- assert(game.government_count > 0 &&
- government >= 0 && government < game.government_count);
-
- req = governments[government].required_tech;
- if (!tech_is_available(pplayer, req)) {
- /* If the technology doesn't "exist" or if there is no way we can
- * ever get it, then we can't change to the gov type even if we have
- * a wonder that would otherwise allow it. */
+ if (government < 0 || government >= game.government_count) {
+ assert(0);
return FALSE;
- } else {
- return (get_invention(pplayer, req) == TECH_KNOWN
- || get_player_bonus(pplayer, EFT_ANY_GOVERNMENT) > 0);
}
+
+ if (get_player_bonus(pplayer, EFT_ANY_GOVERNMENT) > 0) {
+ /* Note, this may allow govs that are on someone else's "tech tree". */
+ return TRUE;
+ }
+
+ return are_reqs_active(TARGET_PLAYER, pplayer, NULL, B_LAST, NULL,
+ gov->req, MAX_NUM_REQS);
}
/***************************************************************
Index: common/government.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/government.h,v
retrieving revision 1.39
diff -u -r1.39 government.h
--- common/government.h 21 Mar 2005 12:55:07 -0000 1.39
+++ common/government.h 26 Mar 2005 06:59:56 -0000
@@ -16,6 +16,7 @@
#include "shared.h"
#include "fc_types.h"
+#include "requirements.h"
struct Sprite; /* opaque; client-gui specific */
@@ -67,7 +68,7 @@
char name_orig[MAX_LEN_NAME]; /* untranslated copy */
char graphic_str[MAX_LEN_NAME];
char graphic_alt[MAX_LEN_NAME];
- int required_tech; /* tech required to change to this gov */
+ struct requirement req[MAX_NUM_REQS];
int ai_better; /* govt AI prefers to this one (hint) */
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.101
diff -u -r1.101 packets.def
--- common/packets.def 26 Mar 2005 05:59:14 -0000 1.101
+++ common/packets.def 26 Mar 2005 06:59:56 -0000
@@ -1044,7 +1044,11 @@
PACKET_RULESET_GOVERNMENT=100;sc,lsend
GOVERNMENT id;
- UINT8 required_tech;
+ UINT8 req_type[MAX_NUM_REQS];
+ UINT8 req_range[MAX_NUM_REQS];
+ UINT8 req_value[MAX_NUM_REQS];
+ BOOL req_survives[MAX_NUM_REQS];
+
UINT8 max_rate;
UINT8 civil_war;
UINT8 martial_law_max;
Index: data/default/governments.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/governments.ruleset,v
retrieving revision 1.28
diff -u -r1.28 governments.ruleset
--- data/default/governments.ruleset 21 Mar 2005 12:55:07 -0000 1.28
+++ data/default/governments.ruleset 26 Mar 2005 06:59:56 -0000
@@ -32,8 +32,7 @@
; Notes on fields:
; name = name of this government form as seen by user
-; tech_req = required advance, names from techs.ruleset, or special:
-; "None" => available from start
+; reqs = requirements for this government (see README.effects)
; graphic = tag specifing preferred graphic
; graphic_alt = alternate graphics tag if preferred is not found;
; should be a standard tag if preferred is not;
@@ -101,7 +100,7 @@
[government_anarchy]
name = _("Anarchy")
-tech_req = "None"
+; No reqs
graphic = "gov.anarchy"
graphic_alt = "-"
flags = "-"
@@ -162,7 +161,7 @@
[government_despotism]
name = _("Despotism")
-tech_req = "None"
+; No reqs
graphic = "gov.despotism"
graphic_alt = "-"
flags = "-"
@@ -221,7 +220,9 @@
[government_monarchy]
name = _("Monarchy")
-tech_req = "Monarchy"
+reqs = { "type", "name", "range"
+ "tech", "Monarchy", "Player"
+ }
graphic = "gov.monarchy"
graphic_alt = "-"
flags = "-"
@@ -280,7 +281,9 @@
[government_communism]
name = _("Communism")
-tech_req = "Communism"
+reqs = { "type", "name", "range"
+ "tech", "Communism", "Player"
+ }
graphic = "gov.communism"
graphic_alt = "-"
flags = "Build_Veteran_Diplomats", "Inspires_Partisans"
@@ -344,7 +347,9 @@
[government_republic]
name = _("Republic")
-tech_req = "The Republic"
+reqs = { "type", "name", "range"
+ "tech", "The Republic", "Player"
+ }
graphic = "gov.republic"
graphic_alt = "-"
flags = "Has_Senate", "Rapture_City_Growth"
@@ -405,7 +410,9 @@
[government_democracy]
name = _("Democracy")
-tech_req = "Democracy"
+reqs = { "type", "name", "range"
+ "tech", "Democracy", "Player"
+ }
graphic = "gov.democracy"
graphic_alt = "-"
flags = "Has_Senate", "Revolution_When_Unhappy",
Index: server/plrhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.c,v
retrieving revision 1.361
diff -u -r1.361 plrhand.c
--- server/plrhand.c 18 Mar 2005 11:26:24 -0000 1.361
+++ server/plrhand.c 26 Mar 2005 06:59:57 -0000
@@ -271,6 +271,7 @@
bool was_first = FALSE;
bool had_embassy[MAX_NUM_PLAYERS];
struct city *pcity;
+ bool can_switch[game.government_count];
players_iterate(aplr) {
had_embassy[aplr->player_no]
@@ -307,12 +308,9 @@
}
government_iterate(gov) {
- if (tech_found == gov->required_tech) {
- notify_player_ex(plr, NULL, E_NEW_GOVERNMENT,
- _("Discovery of %s makes the government form %s"
- " available. You may want to start a revolution."),
- get_tech_name(plr, tech_found), gov->name);
- }
+ /* We do it this way so all requirements are checked, including
+ * statue-of-liberty effects. */
+ can_switch[gov->index] = can_change_to_government(plr, gov->index);
} government_iterate_end;
if (tech_flag(tech_found, TF_BONUS_TECH) && was_first) {
@@ -326,6 +324,16 @@
upgrade_city_rails(plr, was_discovery);
}
+ government_iterate(gov) {
+ if (!can_switch[gov->index]
+ && can_change_to_government(plr, gov->index)) {
+ notify_player_ex(plr, NULL, E_NEW_GOVERNMENT,
+ _("Discovery of %s makes the government form %s"
+ " available. You may want to start a revolution."),
+ get_tech_name(plr, tech_found), gov->name);
+ }
+ } government_iterate_end;
+
/* enhance vision of units inside a fortress */
if (tech_flag(tech_found, TF_WATCHTOWER)) {
unit_list_iterate(plr->units, punit) {
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.237
diff -u -r1.237 ruleset.c
--- server/ruleset.c 26 Mar 2005 05:59:15 -0000 1.237
+++ server/ruleset.c 26 Mar 2005 06:59:58 -0000
@@ -1631,9 +1631,10 @@
/* easy ones: */
government_iterate(g) {
- int i = g->index;
+ int i = g->index, j;
const char *waste_name[] = {NULL, "waste", "corruption",
NULL, NULL, NULL};
+ struct requirement_vector *reqs = lookup_req_list(file, sec[i], "reqs");
if (section_file_lookup(file, "%s.ai_better", sec[i])) {
char entry[100];
@@ -1643,8 +1644,14 @@
} else {
g->ai_better = G_MAGIC;
}
- g->required_tech
- = lookup_tech(file, sec[i], "tech_req", FALSE, filename, g->name);
+ for (j = 0; j < MAX_NUM_REQS; j++) {
+ if (reqs->size > j) {
+ g->req[j] = reqs->p[j];
+ } else {
+ g->req[j].source.type = REQ_NONE;
+ memset(&g->req[j], 0, sizeof(g->req[j]));
+ }
+ }
sz_strlcpy(g->graphic_str,
secfile_lookup_str(file, "%s.graphic", sec[i]));
@@ -2853,7 +2860,12 @@
/* send one packet_government */
gov.id = g->index;
- gov.required_tech = g->required_tech;
+ for (j = 0; j < MAX_NUM_REQS; j++) {
+ req_get_values(&g->req[j],
+ &gov.req_type[j], &gov.req_range[j],
+ &gov.req_survives[j], &gov.req_value[j]);
+ }
+
gov.max_rate = g->max_rate;
gov.civil_war = g->civil_war;
gov.martial_law_max = g->martial_law_max;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Freeciv-Dev] (PR#12659) requirements for governments,
Jason Short <=
|
|