[Freeciv-Dev] (PR#12019) Effects TNG
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12019 >
Here's a new patch. I combined the rulesets with the v4 patch. There
were no other changes.
Bug-hunters, please test. Modpack authors, please comment on the
design. AI people, please review the AI bits (I suggest diff -b).
We'll probably commit this pretty soon.
-jason
Index: ai/aicity.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aicity.c,v
retrieving revision 1.190
diff -u -r1.190 aicity.c
--- ai/aicity.c 22 Jan 2005 19:45:38 -0000 1.190
+++ ai/aicity.c 31 Jan 2005 18:20:53 -0000
@@ -245,6 +245,10 @@
struct tile *ptile = pcity->tile;
bool capital = is_capital(pcity);
struct government *gov = get_gov_pplayer(pplayer);
+ struct req_source source = {
+ .type = REQ_BUILDING,
+ .value.building = id
+ };
/* Base want is calculated above using a more direct approach. */
v += base_want(pplayer, pcity, id);
@@ -262,277 +266,294 @@
cities[REQ_RANGE_CITY] = 1;
cities[REQ_RANGE_LOCAL] = 0;
- /* Calculate desire value. */
- effect_type_vector_iterate(get_building_effect_types(id), ptype) {
- effect_list_iterate(get_building_effects(id, *ptype), peff) {
- if (is_effect_useful(TARGET_BUILDING, pplayer, pcity, id,
- NULL, id, peff)) {
- int amount = peff->value, c = cities[peff->range];
- struct city *palace = find_palace(pplayer);
-
- switch (*ptype) {
- case EFT_PROD_TO_GOLD:
- /* Since coinage contains some entirely spurious ruleset values,
- * we need to return here with some spurious want. */
- pcity->ai.building_want[id] = TRADE_WEIGHTING;
- return;
- /* These have already been evaluated in base_want() */
- case EFT_CAPITAL_CITY:
- case EFT_UPKEEP_FREE:
- case EFT_POLLU_POP_PCT:
- case EFT_POLLU_PROD_PCT:
- case EFT_TRADE_PER_TILE:
- case EFT_TRADE_INC_TILE:
- case EFT_FOOD_INC_TILE:
- case EFT_TRADE_ADD_TILE:
- case EFT_PROD_INC_TILE:
- case EFT_PROD_PER_TILE:
- case EFT_PROD_ADD_TILE:
- case EFT_FOOD_PER_TILE:
- case EFT_FOOD_ADD_TILE:
- case EFT_PROD_BONUS:
- case EFT_TAX_BONUS:
- case EFT_SCIENCE_BONUS:
- case EFT_LUXURY_BONUS:
- case EFT_CORRUPT_PCT:
- case EFT_WASTE_PCT:
- break;
-
- /* WAG evaluated effects */
- case EFT_INCITE_DIST_PCT:
- if (palace) {
- v += real_map_distance(pcity->tile, palace->tile);
- }
- break;
- case EFT_MAKE_HAPPY:
- /* TODO */
- break;
- case EFT_UNIT_RECOVER:
- /* TODO */
- break;
- case EFT_NO_UNHAPPY:
- v += (get_entertainers(pcity)
- + pcity->ppl_unhappy[4]) * 20;
- break;
- case EFT_FORCE_CONTENT:
- if (!government_has_flag(gov, G_NO_UNHAPPY_CITIZENS)) {
- v += (pcity->ppl_unhappy[4]
- + get_entertainers(pcity)) * 20;
- v += 5 * c;
- }
- break;
- case EFT_MAKE_CONTENT_MIL_PER:
- case EFT_MAKE_CONTENT:
- if (!government_has_flag(gov, G_NO_UNHAPPY_CITIZENS)) {
- v += MIN(pcity->ppl_unhappy[4]
- + get_entertainers(pcity),
- amount) * 20;
- v += MIN(amount, 5) * c;
- }
- break;
- case EFT_MAKE_CONTENT_MIL:
- if (!government_has_flag(gov, G_NO_UNHAPPY_CITIZENS)) {
- v += pcity->ppl_unhappy[4] * amount
- * MAX(unit_list_size(pcity->units_supported)
- - gov->free_happy, 0) * 2;
- v += c * MAX(amount + 2 - gov->free_happy, 1);
- }
- break;
- case EFT_TECH_PARASITE:
- v += (total_bulbs_required(pplayer) * (100 - game.freecost)
- * (nplayers - amount)) / (nplayers * amount * 100);
- break;
- case EFT_GROWTH_FOOD:
- v += c * 4 + (amount / 7) * pcity->surplus[O_FOOD];
- break;
- case EFT_AIRLIFT:
- /* FIXME: We need some smart algorithm here. The below is
- * totally braindead. */
- v += c + MIN(ai->stats.units[UCL_LAND], 13);
- break;
- case EFT_ANY_GOVERNMENT:
- if (!can_change_to_government(pplayer, ai->goal.govt.idx)) {
- v += MIN(MIN(ai->goal.govt.val, 65),
- num_unknown_techs_for_goal(pplayer, ai->goal.govt.req) * 10);
- }
- break;
- case EFT_ENABLE_NUKE:
- /* Treat nuke as a Cruise Missile upgrade */
- v += 20 + ai->stats.units[UCL_MISSILE] * 5;
- break;
- case EFT_ENABLE_SPACE:
- if (game.spacerace) {
- v += 5;
- if (ai->diplomacy.production_leader == pplayer) {
- v += 100;
+ effect_list_iterate(get_req_source_effects(&source), peffect) {
+ struct requirement *mypreq;
+ bool useful;
+
+ if (is_effect_disabled(TARGET_BUILDING, pplayer, pcity,
+ id, NULL, peffect)) {
+ continue;
+ }
+
+ mypreq = NULL;
+ useful = TRUE;
+ requirement_list_iterate(peffect->reqs, preq) {
+ if (preq->source.type == REQ_BUILDING
+ && preq->source.value.building == id) {
+ mypreq = preq;
+ }
+ if (!is_req_active(TARGET_BUILDING, pplayer, pcity, id, NULL, preq)) {
+ useful = FALSE;
+ break;
+ }
+ } requirement_list_iterate_end;
+
+ if (useful) {
+ int amount = peffect->value, c = cities[mypreq->range];
+ struct city *palace = find_palace(pplayer);
+
+ switch (peffect->type) {
+ case EFT_PROD_TO_GOLD:
+ /* Since coinage contains some entirely spurious ruleset values,
+ * we need to return here with some spurious want. */
+ pcity->ai.building_want[id] = TRADE_WEIGHTING;
+ return;
+ /* These have already been evaluated in base_want() */
+ case EFT_CAPITAL_CITY:
+ case EFT_UPKEEP_FREE:
+ case EFT_POLLU_POP_PCT:
+ case EFT_POLLU_PROD_PCT:
+ case EFT_TRADE_PER_TILE:
+ case EFT_TRADE_INC_TILE:
+ case EFT_FOOD_INC_TILE:
+ case EFT_TRADE_ADD_TILE:
+ case EFT_PROD_INC_TILE:
+ case EFT_PROD_PER_TILE:
+ case EFT_PROD_ADD_TILE:
+ case EFT_FOOD_PER_TILE:
+ case EFT_FOOD_ADD_TILE:
+ case EFT_PROD_BONUS:
+ case EFT_TAX_BONUS:
+ case EFT_SCIENCE_BONUS:
+ case EFT_LUXURY_BONUS:
+ case EFT_CORRUPT_PCT:
+ case EFT_WASTE_PCT:
+ break;
+
+ /* WAG evaluated effects */
+ case EFT_INCITE_DIST_PCT:
+ if (palace) {
+ v += real_map_distance(pcity->tile, palace->tile);
+ }
+ break;
+ case EFT_MAKE_HAPPY:
+ /* TODO */
+ break;
+ case EFT_UNIT_RECOVER:
+ /* TODO */
+ break;
+ case EFT_NO_UNHAPPY:
+ v += (get_entertainers(pcity)
+ + pcity->ppl_unhappy[4]) * 20;
+ break;
+ case EFT_FORCE_CONTENT:
+ if (!government_has_flag(gov, G_NO_UNHAPPY_CITIZENS)) {
+ v += (pcity->ppl_unhappy[4]
+ + get_entertainers(pcity)) * 20;
+ v += 5 * c;
+ }
+ break;
+ case EFT_MAKE_CONTENT_MIL_PER:
+ case EFT_MAKE_CONTENT:
+ if (!government_has_flag(gov, G_NO_UNHAPPY_CITIZENS)) {
+ v += MIN(pcity->ppl_unhappy[4]
+ + get_entertainers(pcity),
+ amount) * 20;
+ v += MIN(amount, 5) * c;
+ }
+ break;
+ case EFT_MAKE_CONTENT_MIL:
+ if (!government_has_flag(gov, G_NO_UNHAPPY_CITIZENS)) {
+ v += pcity->ppl_unhappy[4] * amount
+ * MAX(unit_list_size(pcity->units_supported)
+ - gov->free_happy, 0) * 2;
+ v += c * MAX(amount + 2 - gov->free_happy, 1);
+ }
+ break;
+ case EFT_TECH_PARASITE:
+ v += (total_bulbs_required(pplayer) * (100 - game.freecost)
+ * (nplayers - amount)) / (nplayers * amount * 100);
+ break;
+ case EFT_GROWTH_FOOD:
+ v += c * 4 + (amount / 7) * pcity->surplus[O_FOOD];
+ break;
+ case EFT_AIRLIFT:
+ /* FIXME: We need some smart algorithm here. The below is
+ * totally braindead. */
+ v += c + MIN(ai->stats.units[UCL_LAND], 13);
+ break;
+ case EFT_ANY_GOVERNMENT:
+ if (!can_change_to_government(pplayer, ai->goal.govt.idx)) {
+ v += MIN(MIN(ai->goal.govt.val, 65),
+ num_unknown_techs_for_goal(pplayer, ai->goal.govt.req) * 10);
+ }
+ break;
+ case EFT_ENABLE_NUKE:
+ /* Treat nuke as a Cruise Missile upgrade */
+ v += 20 + ai->stats.units[UCL_MISSILE] * 5;
+ break;
+ case EFT_ENABLE_SPACE:
+ if (game.spacerace) {
+ v += 5;
+ if (ai->diplomacy.production_leader == pplayer) {
+ v += 100;
+ }
+ }
+ break;
+ case EFT_GIVE_IMM_TECH:
+ v += ((total_bulbs_required(pplayer) * amount
+ + game.researchcost)
+ * TRADE_WEIGHTING - pplayer->research.bulbs_researched
+ * TRADE_WEIGHTING) / MORT;
+ break;
+ case EFT_HAVE_EMBASSIES:
+ v += 5 * nplayers;
+ break;
+ case EFT_REVEAL_CITIES:
+ case EFT_NO_ANARCHY:
+ break; /* Useless for AI */
+ case EFT_NO_SINK_DEEP:
+ v += 15 + ai->stats.triremes * 5;
+ break;
+ case EFT_NUKE_PROOF:
+ if (ai->threats.nuclear) {
+ v += pcity->size * unit_list_size(ptile->units) * (capital + 1);
+ }
+ break;
+ case EFT_REVEAL_MAP:
+ if (!ai->explore.land_done || !ai->explore.sea_done) {
+ v += 10;
+ }
+ break;
+ case EFT_SIZE_UNLIMIT:
+ amount = 20; /* really big city */
+ /* there not being a break here is deliberate, mind you */
+ case EFT_SIZE_ADJ:
+ if (!city_can_grow_to(pcity, pcity->size + 1)) {
+ v += pcity->surplus[O_FOOD] * ai->food_priority * amount;
+ if (pcity->size == game.aqueduct_size) {
+ v += 30 * pcity->surplus[O_FOOD];
+ }
+ }
+ v += c * amount * 4 / game.aqueduct_size;
+ break;
+ case EFT_SS_STRUCTURAL:
+ case EFT_SS_COMPONENT:
+ case EFT_SS_MODULE:
+ if (game.spacerace
+ /* If someone has started building spaceship already or
+ * we have chance to win a spacerace */
+ && (ai->diplomacy.spacerace_leader
+ || ai->diplomacy.production_leader == pplayer)) {
+ v += 95;
+ }
+ break;
+ case EFT_SPY_RESISTANT:
+ /* Uhm, problem: City Wall has -50% here!! */
+ break;
+ case EFT_SEA_MOVE:
+ v += ai->stats.units[UCL_SEA] * 8 * amount;
+ break;
+ case EFT_UNIT_NO_LOSE_POP:
+ v += unit_list_size(ptile->units) * 2;
+ break;
+ case EFT_LAND_REGEN:
+ v += 15 * c + ai->stats.units[UCL_LAND] * 3;
+ break;
+ case EFT_SEA_REGEN:
+ v += 15 * c + ai->stats.units[UCL_SEA] * 3;
+ break;
+ case EFT_AIR_REGEN:
+ v += 15 * c + ai->stats.units[UCL_AIR] * 3;
+ break;
+ case EFT_LAND_VET_COMBAT:
+ v += 2 * c + ai->stats.units[UCL_LAND] * 2;
+ break;
+ case EFT_LAND_VETERAN:
+ v += 5 * c + ai->stats.units[UCL_LAND];
+ break;
+ case EFT_SEA_VETERAN:
+ v += 5 * c + ai->stats.units[UCL_SEA];
+ break;
+ case EFT_AIR_VETERAN:
+ v += 5 * c + ai->stats.units[UCL_AIR];
+ break;
+ case EFT_UPGRADE_UNIT:
+ v += ai->stats.units[UCL_LAST];
+ if (amount == 1) {
+ v *= 2;
+ } else if (amount == 2) {
+ v *= 3;
+ } else {
+ v *= 4;
+ }
+ break;
+ case EFT_SEA_DEFEND:
+ if (ai_handicap(pplayer, H_DEFENSIVE)) {
+ v += amount / 10; /* make AI slow */
+ }
+ if (is_ocean(map_get_terrain(pcity->tile))) {
+ v += ai->threats.ocean[-map_get_continent(pcity->tile)]
+ ? amount/5 : amount/20;
+ } else {
+ adjc_iterate(pcity->tile, tile2) {
+ if (is_ocean(map_get_terrain(tile2))) {
+ if (ai->threats.ocean[-map_get_continent(tile2)]) {
+ v += amount/5;
+ break;
+ }
+ }
+ } adjc_iterate_end;
+ }
+ v += (amount/20 + ai->threats.invasions - 1) * c; /* for wonder */
+ if (capital && ai->threats.invasions) {
+ v += amount; /* defend capital! */
+ }
+ break;
+ case EFT_AIR_DEFEND:
+ if (ai_handicap(pplayer, H_DEFENSIVE)) {
+ v += amount / 15; /* make AI slow */
+ }
+ v += (ai->threats.air && ai->threats.continent[ptile->continent])
+ ? amount/10 * 5 + amount/10 * c : c;
+ break;
+ case EFT_MISSILE_DEFEND:
+ if (ai->threats.missile
+ && (ai->threats.continent[ptile->continent] || capital)) {
+ v += amount/10 * 5 + (amount/10 - 1) * c;
+ }
+ break;
+ case EFT_LAND_DEFEND:
+ if (ai_handicap(pplayer, H_DEFENSIVE)) {
+ v += amount / 10; /* make AI slow */
+ }
+ if (ai->threats.continent[ptile->continent]
+ || capital
+ || (ai->threats.invasions
+ && is_water_adjacent_to_tile(pcity->tile))) {
+ v += amount / (!ai->threats.igwall ? (15 - capital * 5) : 15);
+ }
+ v += (1 + ai->threats.invasions + !ai->threats.igwall) * c;
+ break;
+ case EFT_NO_INCITE:
+ if (!government_has_flag(gov, G_UNBRIBABLE)) {
+ v += MAX((game.diplchance * 2 - game.incite_cost.total_factor) / 2
+ - game.incite_cost.improvement_factor * 5
+ - game.incite_cost.unit_factor * 5, 0);
+ }
+ break;
+ case EFT_REGEN_REPUTATION:
+ v += (GAME_MAX_REPUTATION - pplayer->reputation) * 50 /
+ GAME_MAX_REPUTATION +
+ amount * 4;
+ break;
+ case EFT_GAIN_AI_LOVE:
+ players_iterate(aplayer) {
+ if (aplayer->ai.control) {
+ if (ai_handicap(pplayer, H_DEFENSIVE)) {
+ v += amount / 10;
+ } else {
+ v += amount / 20;
}
}
- break;
- case EFT_GIVE_IMM_TECH:
- v += ((total_bulbs_required(pplayer) * amount
- + game.researchcost)
- * TRADE_WEIGHTING - pplayer->research.bulbs_researched
- * TRADE_WEIGHTING) / MORT;
- break;
- case EFT_HAVE_EMBASSIES:
- v += 5 * nplayers;
- break;
- case EFT_REVEAL_CITIES:
- case EFT_NO_ANARCHY:
- break; /* Useless for AI */
- case EFT_NO_SINK_DEEP:
- v += 15 + ai->stats.triremes * 5;
- break;
- case EFT_NUKE_PROOF:
- if (ai->threats.nuclear) {
- v += pcity->size * unit_list_size(ptile->units) * (capital + 1);
- }
- break;
- case EFT_REVEAL_MAP:
- if (!ai->explore.land_done || !ai->explore.sea_done) {
- v += 10;
- }
- break;
- case EFT_SIZE_UNLIMIT:
- amount = 20; /* really big city */
- /* there not being a break here is deliberate, mind you */
- case EFT_SIZE_ADJ:
- if (!city_can_grow_to(pcity, pcity->size + 1)) {
- v += pcity->surplus[O_FOOD] * ai->food_priority * amount;
- if (pcity->size == game.aqueduct_size) {
- v += 30 * pcity->surplus[O_FOOD];
- }
- }
- v += c * amount * 4 / game.aqueduct_size;
- break;
- case EFT_SS_STRUCTURAL:
- case EFT_SS_COMPONENT:
- case EFT_SS_MODULE:
- if (game.spacerace
- /* If someone has started building spaceship already or
- * we have chance to win a spacerace */
- && (ai->diplomacy.spacerace_leader
- || ai->diplomacy.production_leader == pplayer)) {
- v += 95;
- }
- break;
- case EFT_SPY_RESISTANT:
- /* Uhm, problem: City Wall has -50% here!! */
- break;
- case EFT_SEA_MOVE:
- v += ai->stats.units[UCL_SEA] * 8 * amount;
- break;
- case EFT_UNIT_NO_LOSE_POP:
- v += unit_list_size(ptile->units) * 2;
- break;
- case EFT_LAND_REGEN:
- v += 15 * c + ai->stats.units[UCL_LAND] * 3;
- break;
- case EFT_SEA_REGEN:
- v += 15 * c + ai->stats.units[UCL_SEA] * 3;
- break;
- case EFT_AIR_REGEN:
- v += 15 * c + ai->stats.units[UCL_AIR] * 3;
- break;
- case EFT_LAND_VET_COMBAT:
- v += 2 * c + ai->stats.units[UCL_LAND] * 2;
- break;
- case EFT_LAND_VETERAN:
- v += 5 * c + ai->stats.units[UCL_LAND];
- break;
- case EFT_SEA_VETERAN:
- v += 5 * c + ai->stats.units[UCL_SEA];
- break;
- case EFT_AIR_VETERAN:
- v += 5 * c + ai->stats.units[UCL_AIR];
- break;
- case EFT_UPGRADE_UNIT:
- v += ai->stats.units[UCL_LAST];
- if (amount == 1) {
- v *= 2;
- } else if (amount == 2) {
- v *= 3;
- } else {
- v *= 4;
- }
- break;
- case EFT_SEA_DEFEND:
- if (ai_handicap(pplayer, H_DEFENSIVE)) {
- v += amount / 10; /* make AI slow */
- }
- if (is_ocean(map_get_terrain(pcity->tile))) {
- v += ai->threats.ocean[-map_get_continent(pcity->tile)]
- ? amount/5 : amount/20;
- } else {
- adjc_iterate(pcity->tile, tile2) {
- if (is_ocean(map_get_terrain(tile2))) {
- if (ai->threats.ocean[-map_get_continent(tile2)]) {
- v += amount/5;
- break;
- }
- }
- } adjc_iterate_end;
- }
- v += (amount/20 + ai->threats.invasions - 1) * c; /* for wonder */
- if (capital && ai->threats.invasions) {
- v += amount; /* defend capital! */
- }
- break;
- case EFT_AIR_DEFEND:
- if (ai_handicap(pplayer, H_DEFENSIVE)) {
- v += amount / 15; /* make AI slow */
- }
- v += (ai->threats.air && ai->threats.continent[ptile->continent])
- ? amount/10 * 5 + amount/10 * c : c;
- break;
- case EFT_MISSILE_DEFEND:
- if (ai->threats.missile
- && (ai->threats.continent[ptile->continent] || capital)) {
- v += amount/10 * 5 + (amount/10 - 1) * c;
- }
- break;
- case EFT_LAND_DEFEND:
- if (ai_handicap(pplayer, H_DEFENSIVE)) {
- v += amount / 10; /* make AI slow */
- }
- if (ai->threats.continent[ptile->continent]
- || capital
- || (ai->threats.invasions
- && is_water_adjacent_to_tile(pcity->tile))) {
- v += amount / (!ai->threats.igwall ? (15 - capital * 5) : 15);
- }
- v += (1 + ai->threats.invasions + !ai->threats.igwall) * c;
- break;
- case EFT_NO_INCITE:
- if (!government_has_flag(gov, G_UNBRIBABLE)) {
- v += MAX((game.diplchance * 2 - game.incite_cost.total_factor) / 2
- - game.incite_cost.improvement_factor * 5
- - game.incite_cost.unit_factor * 5, 0);
- }
- break;
- case EFT_REGEN_REPUTATION:
- v += (GAME_MAX_REPUTATION - pplayer->reputation) * 50 /
- GAME_MAX_REPUTATION +
- amount * 4;
- break;
- case EFT_GAIN_AI_LOVE:
- players_iterate(aplayer) {
- if (aplayer->ai.control) {
- if (ai_handicap(pplayer, H_DEFENSIVE)) {
- v += amount / 10;
- } else {
- v += amount / 20;
- }
- }
- } players_iterate_end;
- break;
- case EFT_LAST:
- freelog(LOG_ERROR, "Bad effect type.");
- break;
- }
+ } players_iterate_end;
+ break;
+ case EFT_LAST:
+ freelog(LOG_ERROR, "Bad effect type.");
+ break;
}
- } effect_list_iterate_end;
- } effect_type_vector_iterate_end;
+ }
+ } effect_list_iterate_end;
/* Reduce want if building gets obsoleted soon */
if (tech_exists(pimpr->obsolete_by)) {
Index: ai/aidata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidata.c,v
retrieving revision 1.49
diff -u -r1.49 aidata.c
--- ai/aidata.c 22 Jan 2005 19:45:38 -0000 1.49
+++ ai/aidata.c 31 Jan 2005 18:20:53 -0000
@@ -59,11 +59,16 @@
memset(count, 0, sizeof(count));
impr_type_iterate(id) {
+ struct req_source source = {
+ .type = REQ_BUILDING,
+ .value.building = id
+ };
+
ai->impr_calc[id] = AI_IMPR_ESTIMATE;
/* Find largest extension */
- effect_type_vector_iterate(get_building_effect_types(id), ptype) {
- switch (*ptype) {
+ effect_list_iterate(get_req_source_effects(&source), peffect) {
+ switch (peffect->type) {
#if 0
/* TODO */
case EFT_FORCE_CONTENT:
@@ -92,19 +97,21 @@
case EFT_TRADE_INC_TILE:
case EFT_TRADE_PER_TILE:
case EFT_UPKEEP_FREE:
- effect_list_iterate(get_building_effects(id, *ptype), peff) {
- ai->impr_calc[id] = AI_IMPR_CALCULATE;
- if (peff->range > ai->impr_range[id]) {
- ai->impr_range[id] = peff->range;
- }
- } effect_list_iterate_end;
+ requirement_list_iterate(peffect->reqs, preq) {
+ if (preq->source.type == REQ_BUILDING
+ && preq->source.value.building == id) {
+ ai->impr_calc[id] = AI_IMPR_CALCULATE;
+ if (preq->range > ai->impr_range[id]) {
+ ai->impr_range[id] = preq->range;
+ }
+ }
+ } requirement_list_iterate_end;
break;
default:
/* Nothing! */
break;
}
- } effect_type_vector_iterate_end;
-
+ } effect_list_iterate_end;
} impr_type_iterate_end;
}
Index: client/citydlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/citydlg_common.c,v
retrieving revision 1.57
diff -u -r1.57 citydlg_common.c
--- client/citydlg_common.c 22 Jan 2005 19:45:38 -0000 1.57
+++ client/citydlg_common.c 31 Jan 2005 18:20:54 -0000
@@ -439,22 +439,26 @@
if (eft != EFT_LAST) {
int base = total, bonus = 100;
- struct effect_source_vector sources;
+ struct effect_list *plist = effect_list_new();
- (void) get_city_bonus_sources(&sources, pcity, eft);
+ (void) get_city_bonus_effects(plist, pcity, eft);
- effect_source_vector_iterate(&sources, s) {
+ effect_list_iterate(plist, peffect) {
+ char buf2[512];
int new_total;
- bonus += s->effect_value;
+ get_effect_req_text(peffect, buf2, sizeof(buf2));
+
+ bonus += peffect->value;
new_total = bonus * base / 100;
cat_snprintf(buf, bufsz,
_("%+4d : Bonus from %s (%+d%%)\n"),
- (new_total - total), get_improvement_name(s->building),
- s->effect_value);
+ (new_total - total), buf2,
+ peffect->value);
total = new_total;
- } effect_source_vector_iterate_end;
- effect_source_vector_free(&sources);
+ } effect_list_iterate_end;
+ effect_list_unlink_all(plist);
+ effect_list_free(plist);
}
if (pcity->waste[otype] != 0) {
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.461
diff -u -r1.461 packhand.c
--- client/packhand.c 29 Jan 2005 17:58:17 -0000 1.461
+++ client/packhand.c 31 Jan 2005 18:20:54 -0000
@@ -2833,31 +2833,18 @@
}
/**************************************************************************
- Add group data to ruleset cache.
+ Add effect data to ruleset cache.
**************************************************************************/
-void handle_ruleset_cache_group(struct packet_ruleset_cache_group *packet)
+void handle_ruleset_effect(struct packet_ruleset_effect *packet)
{
- struct effect_group *pgroup;
- int i;
-
- pgroup = effect_group_new(packet->name);
-
- for (i = 0; i < packet->num_elements; i++) {
- effect_group_add_element(pgroup, packet->source_buildings[i],
- packet->ranges[i], packet->survives[i]);
- }
+ recv_ruleset_effect(packet);
}
/**************************************************************************
- Add effect data to ruleset cache.
+ Add effect requirement data to ruleset cache.
**************************************************************************/
-void handle_ruleset_cache_effect(struct packet_ruleset_cache_effect *packet)
+void handle_ruleset_effect_req(struct packet_ruleset_effect_req *packet)
{
- struct requirement req = req_from_values(packet->req_type, REQ_RANGE_CITY,
- FALSE, packet->req_value);
-
- ruleset_cache_add(packet->id, packet->effect_type, packet->range,
- packet->survives, packet->eff_value,
- &req, packet->group_id);
+ recv_ruleset_effect_req(packet);
}
Index: client/text.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/text.c,v
retrieving revision 1.21
diff -u -r1.21 text.c
--- client/text.c 22 Jan 2005 19:45:39 -0000 1.21
+++ client/text.c 31 Jan 2005 18:20:54 -0000
@@ -724,17 +724,21 @@
const char *get_happiness_buildings(const struct city *pcity)
{
int faces = 0;
- struct effect_source_vector sources;
+ struct effect_list *plist = effect_list_new();
+ char buf[512];
INIT;
add_line(_("Buildings: "));
- get_city_bonus_sources(&sources, pcity, EFT_MAKE_CONTENT);
- effect_source_vector_iterate(&sources, src) {
+ get_city_bonus_effects(plist, pcity, EFT_MAKE_CONTENT);
+
+ effect_list_iterate(plist, peffect) {
faces++;
- add(_("%s. "), get_improvement_name(src->building));
- } effect_source_vector_iterate_end;
- effect_source_vector_free(&sources);
+ get_effect_req_text(peffect, buf, sizeof(buf));
+ add(_("%s. "), buf);
+ } effect_list_iterate_end;
+ effect_list_unlink_all(plist);
+ effect_list_free(plist);
if (faces == 0) {
add(_("None. "));
@@ -749,31 +753,23 @@
const char *get_happiness_wonders(const struct city *pcity)
{
int faces = 0;
- struct effect_source_vector sources;
+ struct effect_list *plist = effect_list_new();
+ char buf[512];
INIT;
add_line(_("Wonders: "));
+ get_city_bonus_effects(plist, pcity, EFT_MAKE_HAPPY);
+ get_city_bonus_effects(plist, pcity, EFT_FORCE_CONTENT);
+ get_city_bonus_effects(plist, pcity, EFT_NO_UNHAPPY);
- get_city_bonus_sources(&sources, pcity, EFT_MAKE_HAPPY);
- effect_source_vector_iterate(&sources, src) {
- faces++;
- add(_("%s. "), get_improvement_name(src->building));
- } effect_source_vector_iterate_end;
- effect_source_vector_free(&sources);
-
- get_city_bonus_sources(&sources, pcity, EFT_FORCE_CONTENT);
- effect_source_vector_iterate(&sources, src) {
+ effect_list_iterate(plist, peffect) {
faces++;
- add(_("%s. "), get_improvement_name(src->building));
- } effect_source_vector_iterate_end;
- effect_source_vector_free(&sources);
+ get_effect_req_text(peffect, buf, sizeof(buf));
+ add(_("%s. "), buf);
+ } effect_list_iterate_end;
- get_city_bonus_sources(&sources, pcity, EFT_NO_UNHAPPY);
- effect_source_vector_iterate(&sources, src) {
- faces++;
- add(_("%s. "), get_improvement_name(src->building));
- } effect_source_vector_iterate_end;
- effect_source_vector_free(&sources);
+ effect_list_unlink_all(plist);
+ effect_list_free(plist);
if (faces == 0) {
add(_("None. "));
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.308
diff -u -r1.308 city.c
--- common/city.c 29 Jan 2005 08:51:18 -0000 1.308
+++ common/city.c 31 Jan 2005 18:20:55 -0000
@@ -671,7 +671,7 @@
for (i = 0; i < MAX_NUM_REQS; i++) {
struct requirement *req = &game.rgame.specialists[type].req[i];
- if (req->type == REQ_NONE) {
+ if (req->source.type == REQ_NONE) {
break; /* Short-circuit any more checks. */
} else if (!is_req_active(TARGET_CITY, city_owner(pcity), pcity,
B_LAST, NULL, req)) {
Index: common/effects.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/effects.c,v
retrieving revision 1.21
diff -u -r1.21 effects.c
--- common/effects.c 22 Jan 2005 19:45:41 -0000 1.21
+++ common/effects.c 31 Jan 2005 18:20:55 -0000
@@ -212,152 +212,114 @@
number of possible sources increases.
**************************************************************************/
-/*
- * A group lists which sources are in it and at what range.
- * Each effect also lists which group it is in. So an effect is in the
- * group if its source is listed in the group, and the effect lists the
- * group as its own.
- *
- * Only the first applicable effect in a group will be active. Any others
- * are simply ignored.
- *
- * Actually this isn't quite true. The check is done on buildings, not
- * on effects. A building in a group may obsolete the effect of a building
- * later in the group, even if the first building doesn't have any effects
- * that are actually in the group. However only the effects of the second
- * building that are actually in the group will be obsoleted.
- */
-struct effect_group_element {
- Impr_Type_id source_building;
- enum req_range range;
- bool survives;
-};
-
-#define SPECLIST_TAG effect_group_element
-#define SPECLIST_TYPE struct effect_group_element
-#include "speclist.h"
-
-#define effect_group_element_list_iterate(list, elt) \
- TYPED_LIST_ITERATE(struct effect_group_element, list, elt)
-#define effect_group_element_list_iterate_end LIST_ITERATE_END
-
-struct effect_group {
- char *name;
- int id;
- struct effect_group_element_list *elements;
-};
-
-#define SPECLIST_TAG effect_group
-#define SPECLIST_TYPE struct effect_group
-#include "speclist.h"
-
-#define effect_group_list_iterate(list, pgroup) \
- TYPED_LIST_ITERATE(struct effect_group, list, pgroup)
-#define effect_group_list_iterate_end LIST_ITERATE_END
-
/**************************************************************************
Ruleset cache. The cache is created during ruleset loading and the data
is organized to enable fast queries.
**************************************************************************/
static struct {
- struct {
- /* This cache shows for each effect, which buildings provide it. */
- struct building_vector buildings;
+ /* A single list containing every effect. */
+ struct effect_list *tracker;
- /* This array provides a full list of the effects of this type provided
- * by each building. (It's not really a cache, it's the real data.) */
- struct effect_list *buckets[B_LAST];
- } effects[EFT_LAST];
+ /* This array provides a full list of the effects of this type
+ * (It's not really a cache, it's the real data.) */
+ struct effect_list *effects[EFT_LAST];
- /* This cache shows for each building, which effect types it provides. */
struct {
- struct effect_type_vector types;
- } buildings[B_LAST];
+ /* This cache shows for each building, which effects it provides. */
+ struct effect_list *buildings[B_LAST];
+ } reqs;
} ruleset_cache;
-static struct effect_group_list *groups;
-static int next_group_id;
-
/**************************************************************************
- Get a vector of buildings which grant the effect type.
+ Get a list of effects of this type.
**************************************************************************/
-static struct building_vector *get_buildings_with_effect(enum effect_type e)
+static struct effect_list *get_effects(enum effect_type effect_type)
{
- return &ruleset_cache.effects[e].buildings;
+ return ruleset_cache.effects[effect_type];
}
/**************************************************************************
- Get a list of effects of this type granted by a building.
-**************************************************************************/
-struct effect_list *get_building_effects(Impr_Type_id building,
- enum effect_type effect_type)
-{
- return ruleset_cache.effects[effect_type].buckets[building];
-}
+ Get a list of effects with this requirement source.
-/**************************************************************************
- Get a vector of effect types granted by a building.
+ Note: currently only buildings are supported.
**************************************************************************/
-struct effect_type_vector *get_building_effect_types(Impr_Type_id id)
+struct effect_list *get_req_source_effects(struct req_source *psource)
{
- return &ruleset_cache.buildings[id].types;
+ switch (psource->type) {
+ case REQ_BUILDING:
+ return ruleset_cache.reqs.buildings[psource->value.building];
+ default:
+ return NULL;
+ }
}
/**************************************************************************
- Create a new effects group.
+ Add effect to ruleset cache.
**************************************************************************/
-struct effect_group *effect_group_new(const char *name)
+struct effect *effect_new(enum effect_type type, int value)
{
- struct effect_group *group;
+ struct effect *peffect;
- /* Create the group. */
- group = fc_malloc(sizeof(*group));
- group->name = mystrdup(name);
- group->id = next_group_id++;
- group->elements = effect_group_element_list_new();
+ /* Create the effect. */
+ peffect = fc_malloc(sizeof(*peffect));
+ peffect->type = type;
+ peffect->value = value;
- /* Add this group to the global list of groups. */
- effect_group_list_append(groups, group);
+ peffect->reqs = requirement_list_new();
+ peffect->nreqs = requirement_list_new();
- return group;
+ /* Now add the effect to the ruleset cache. */
+ effect_list_append(ruleset_cache.tracker, peffect);
+ effect_list_append(get_effects(type), peffect);
+ return peffect;
}
/**************************************************************************
- Add a source to an existing effects group.
+ Free effect.
**************************************************************************/
-void effect_group_add_element(struct effect_group *group,
- Impr_Type_id source_building,
- enum req_range range, bool survives)
+static void effect_free(struct effect *peffect)
{
- struct effect_group_element *elt;
+ requirement_list_iterate(peffect->reqs, preq) {
+ free(preq);
+ } requirement_list_iterate_end;
+ requirement_list_unlink_all(peffect->reqs);
+ requirement_list_free(peffect->reqs);
- /* Create the element. */
- elt = fc_malloc(sizeof(*elt));
- elt->source_building = source_building;
- elt->range = range;
- elt->survives = survives;
+ requirement_list_iterate(peffect->nreqs, preq) {
+ free(preq);
+ } requirement_list_iterate_end;
+ requirement_list_unlink_all(peffect->nreqs);
+ requirement_list_free(peffect->nreqs);
- /* Append it to the group. */
- effect_group_element_list_append(group->elements, elt);
+ free(peffect);
}
/**************************************************************************
- Find the id of an effects group by name. Returns -1 if the group is not
- found.
+ Append requirement to effect.
**************************************************************************/
-int find_effect_group_id(const char *name)
+void effect_req_append(struct effect *peffect, bool neg,
+ struct requirement *preq)
{
- int group_id = 0;
+ struct requirement_list *req_list;
- effect_group_list_iterate(groups, pgroup) {
- if (0 == mystrcasecmp(pgroup->name, name)) {
- return group_id;
- }
- group_id++;
- } effect_group_list_iterate_end;
+ if (neg) {
+ req_list = peffect->nreqs;
+ } else {
+ req_list = peffect->reqs;
+ }
+
+ /* Append requirement to the effect. */
+ requirement_list_append(req_list, preq);
- return -1;
+ /* Add effect to the source's effect list. */
+ if (!neg) {
+ struct effect_list *eff_list = get_req_source_effects(&preq->source);
+
+ if (eff_list) {
+ effect_list_append(eff_list, peffect);
+ }
+ }
}
/**************************************************************************
@@ -367,21 +329,15 @@
**************************************************************************/
void ruleset_cache_init(void)
{
- int i, j;
-
- groups = effect_group_list_new();
- next_group_id = 0;
+ int i;
- for (i = 0; i < ARRAY_SIZE(ruleset_cache.buildings); i++) {
- effect_type_vector_init(get_building_effect_types(i));
- }
+ ruleset_cache.tracker = effect_list_new();
for (i = 0; i < ARRAY_SIZE(ruleset_cache.effects); i++) {
- building_vector_init(get_buildings_with_effect(i));
-
- for (j = 0; j < ARRAY_SIZE(ruleset_cache.effects[i].buckets); j++) {
- ruleset_cache.effects[i].buckets[j] = effect_list_new();
- }
+ ruleset_cache.effects[i] = effect_list_new();
+ }
+ for (i = 0; i < ARRAY_SIZE(ruleset_cache.reqs.buildings); i++) {
+ ruleset_cache.reqs.buildings[i] = effect_list_new();
}
}
@@ -391,166 +347,71 @@
**************************************************************************/
void ruleset_cache_free(void)
{
- int i, j;
+ int i;
+ struct effect_list *plist = ruleset_cache.tracker;
- for (i = 0; i < ARRAY_SIZE(ruleset_cache.buildings); i++) {
- effect_type_vector_free(get_building_effect_types(i));
+ if (plist) {
+ effect_list_iterate(plist, peffect) {
+ effect_free(peffect);
+ } effect_list_iterate_end;
+ effect_list_unlink_all(plist);
+ effect_list_free(plist);
+ ruleset_cache.tracker = NULL;
}
for (i = 0; i < ARRAY_SIZE(ruleset_cache.effects); i++) {
- building_vector_free(get_buildings_with_effect(i));
-
- for (j = 0; j < ARRAY_SIZE(ruleset_cache.effects[i].buckets); j++) {
- struct effect_list *plist = get_building_effects(j, i);
-
- if (plist != NULL) {
- effect_list_iterate(plist, peffect) {
- /* Allocated in ruleset_cache_add. */
- free(peffect);
- } effect_list_iterate_end;
- effect_list_unlink_all(plist);
- effect_list_free(plist);
- }
- }
- }
- if (groups != NULL) {
- effect_group_list_unlink_all(groups);
- effect_group_list_free(groups);
- }
-}
-
-/**************************************************************************
- Add effect to ruleset cache.
-**************************************************************************/
-void ruleset_cache_add(Impr_Type_id source, enum effect_type effect_type,
- enum req_range range, bool survives, int eff_value,
- struct requirement *req,
- int group_id)
-{
- struct effect *peffect;
-
- /* Create the effect. */
- peffect = fc_malloc(sizeof(*peffect));
- peffect->range = range;
- peffect->survives = survives;
- peffect->value = eff_value;
-
- /* Set effect's requirement data. */
- peffect->req = *req;
-
- /* Find the effect's group. */
- if (group_id >= 0) {
- peffect->group = effect_group_list_get(groups, group_id);
- } else {
- peffect->group = NULL;
- }
-
- /* Now add the effect to the ruleset cache. */
- effect_list_append(get_building_effects(source, effect_type),
- peffect);
+ struct effect_list *plist = get_effects(i);
- /* Add building type to the effect type's buildings vector. */
- {
- struct building_vector *vec;
- Impr_Type_id *pbldg;
-
- vec = get_buildings_with_effect(effect_type);
-
- /* Append this building to the list of buildings providing the effect.
- * There is a sanity check to prevent it from being added more than
- * once. (It is possible the same building would have multiple effects
- * of the same type, in which case we don't want to add the building
- * to the list twice. However this does assume that all effects from
- * one building are processed before moving on to the next building. */
- if (!(pbldg = building_vector_get(vec, -1)) || *pbldg != source) {
- building_vector_append(vec, &source);
+ if (plist) {
+ effect_list_unlink_all(plist);
+ effect_list_free(plist);
+ ruleset_cache.effects[i] = NULL;
}
}
- /* Add effect type to the building's effect types vector. */
- {
- struct effect_type_vector *vec;
- bool exists = FALSE;
-
- vec = get_building_effect_types(source);
-
- /* See if it's already in the list. */
- effect_type_vector_iterate(vec, ptype) {
- if (*ptype == effect_type) {
- exists = TRUE;
- break;
- }
- } effect_type_vector_iterate_end;
-
- /* And if not, append it. */
- if (!exists) {
- effect_type_vector_append(vec, &effect_type);
+ for (i = 0; i < ARRAY_SIZE(ruleset_cache.reqs.buildings); i++) {
+ struct req_source source = {
+ .type = REQ_BUILDING,
+ .value.building = i
+ };
+ struct effect_list *plist = get_req_source_effects(&source);
+
+ if (plist) {
+ effect_list_unlink_all(plist);
+ effect_list_free(plist);
+ ruleset_cache.reqs.buildings[i] = NULL;
}
}
}
/**************************************************************************
- Send the ruleset cache groups data.
+ Receives a new effect. This is called by the client when the packet
+ arrives.
**************************************************************************/
-static void send_ruleset_cache_groups(struct conn_list *dest)
+void recv_ruleset_effect(struct packet_ruleset_effect *packet)
{
- struct packet_ruleset_cache_group packet;
- int i;
-
- effect_group_list_iterate(groups, pgroup) {
- sz_strlcpy(packet.name, pgroup->name);
-
- packet.num_elements = effect_group_element_list_size(pgroup->elements);
- for (i = 0; i < packet.num_elements; i++) {
- struct effect_group_element *elt;
-
- elt = effect_group_element_list_get(pgroup->elements, i);
- packet.source_buildings[i] = elt->source_building;
- packet.ranges[i] = elt->range;
- packet.survives[i] = elt->survives;
- }
-
- lsend_packet_ruleset_cache_group(dest, &packet);
- } effect_group_list_iterate_end;
+ effect_new(packet->effect_type, packet->effect_value);
}
/**************************************************************************
- Send the ruleset cache effects data.
+ Receives a new effect *requirement*. This is called by the client when
+ the packet arrives.
**************************************************************************/
-static void send_ruleset_cache_effects(struct conn_list *dest)
+void recv_ruleset_effect_req(struct packet_ruleset_effect_req *packet)
{
- struct packet_ruleset_cache_effect packet;
- enum effect_type effect_type;
-
- for (effect_type = 0; effect_type < EFT_LAST; effect_type++) {
- packet.effect_type = effect_type;
-
- building_vector_iterate(get_buildings_with_effect(effect_type),
- building) {
- int dummy_type, dummy_range;
- bool dummy_survives;
-
- packet.id = *building;
-
- effect_list_iterate(get_building_effects(*building, effect_type),
- peffect) {
- packet.range = peffect->range;
- packet.survives = peffect->survives;
- packet.eff_value = peffect->value;
- packet.req_type = peffect->req.type;
+ if (packet->effect_id != effect_list_size(ruleset_cache.tracker) - 1) {
+ freelog(LOG_ERROR, "Bug in recv_ruleset_effect_req.");
+ } else {
+ struct effect *peffect = effect_list_get(ruleset_cache.tracker, -1);
+ struct requirement req, *preq;
- if (peffect->group) {
- packet.group_id = peffect->group->id;
- } else {
- packet.group_id = -1;
- }
+ req = req_from_values(packet->source_type, packet->range, packet->survives,
+ packet->source_value);
- req_get_values(&peffect->req, &dummy_type,
- &dummy_range, &dummy_survives, &packet.req_value);
+ preq = fc_malloc(sizeof(*preq));
+ *preq = req;
- lsend_packet_ruleset_cache_effect(dest, &packet);
- } effect_list_iterate_end;
- } building_vector_iterate_end;
+ effect_req_append(peffect, packet->neg, preq);
}
}
@@ -559,8 +420,50 @@
**************************************************************************/
void send_ruleset_cache(struct conn_list *dest)
{
- send_ruleset_cache_groups(dest);
- send_ruleset_cache_effects(dest);
+ unsigned id = 0;
+
+ effect_list_iterate(ruleset_cache.tracker, peffect) {
+ struct packet_ruleset_effect packet;
+
+ packet.effect_type = peffect->type;
+ packet.effect_value = peffect->value;
+
+ lsend_packet_ruleset_effect(dest, &packet);
+
+ requirement_list_iterate(peffect->reqs, preq) {
+ struct packet_ruleset_effect_req packet;
+ int type, range, value;
+ bool survives;
+
+ req_get_values(preq, &type, &range, &survives, &value);
+ packet.effect_id = id;
+ packet.neg = FALSE;
+ packet.source_type = type;
+ packet.source_value = value;
+ packet.range = range;
+ packet.survives = survives;
+
+ lsend_packet_ruleset_effect_req(dest, &packet);
+ } requirement_list_iterate_end;
+
+ requirement_list_iterate(peffect->nreqs, preq) {
+ struct packet_ruleset_effect_req packet;
+ int type, range, value;
+ bool survives;
+
+ req_get_values(preq, &type, &range, &survives, &value);
+ packet.effect_id = id;
+ packet.neg = TRUE;
+ packet.source_type = type;
+ packet.source_value = value;
+ packet.range = range;
+ packet.survives = survives;
+
+ lsend_packet_ruleset_effect_req(dest, &packet);
+ } requirement_list_iterate_end;
+
+ id++;
+ } effect_list_iterate_end;
}
/**************************************************************************
@@ -574,13 +477,19 @@
{
/* FIXME: this just returns the first building. it should return the best
* building instead. */
- building_vector_iterate(get_buildings_with_effect(effect_type), pbldg) {
- if (can_player_build_improvement(pplayer, *pbldg)
- && !improvement_obsolete(pplayer, *pbldg)
- && is_improvement(*pbldg)) {
- return *pbldg;
- }
- } building_vector_iterate_end;
+ effect_list_iterate(get_effects(effect_type), peffect) {
+ requirement_list_iterate(peffect->reqs, preq) {
+ if (preq->source.type == REQ_BUILDING) {
+ Impr_Type_id id = preq->source.value.building;
+
+ if (can_player_build_improvement(pplayer, id)
+ && !improvement_obsolete(pplayer, id)
+ && is_improvement(id)) {
+ return id;
+ }
+ }
+ } requirement_list_iterate_end;
+ } effect_list_iterate_end;
return B_LAST;
}
@@ -589,9 +498,13 @@
**************************************************************************/
Impr_Type_id get_building_for_effect(enum effect_type effect_type)
{
- building_vector_iterate(get_buildings_with_effect(effect_type), pbldg) {
- return *pbldg;
- } building_vector_iterate_end;
+ effect_list_iterate(get_effects(effect_type), peffect) {
+ requirement_list_iterate(peffect->reqs, preq) {
+ if (preq->source.type == REQ_BUILDING) {
+ return preq->source.value.building;
+ }
+ } requirement_list_iterate_end;
+ } effect_list_iterate_end;
return B_LAST;
}
@@ -605,65 +518,86 @@
**************************************************************************/
bool building_has_effect(Impr_Type_id id, enum effect_type effect)
{
- return (effect_list_size(get_building_effects(id, effect)) > 0);
-}
+ struct req_source source;
+ struct effect_list *plist;
-/**************************************************************************
- Is the effect from the source building redundant on the given target
- (i.e. are its effects replaced by other sources in the group)?
+ source.type = REQ_BUILDING;
+ source.value.building = id;
- target gives the type of the target
- (player,pcity,building) gives the exact target
- source is the source type of the effect
- peffect is the exact effect
-**************************************************************************/
-static bool is_effect_redundant(enum target_type target,
- const struct player *target_player,
- const struct city *target_city,
- Impr_Type_id target_building,
- Impr_Type_id source,
- const struct effect *peffect)
-{
- if (!peffect->group) {
- /* No group: the effect can't be redundant. */
+ plist = get_req_source_effects(&source);
+
+ if (!plist) {
return FALSE;
}
- /* If there is more than one building in the same effects "group", then
- * only the first one that exists can be active. */
- effect_group_element_list_iterate(peffect->group->elements, elt) {
- if (elt->source_building == source) {
- return FALSE;
- } else {
- if (count_buildings_in_range(target, target_player, target_city,
- target_building, elt->range,
- elt->survives, elt->source_building) > 0) {
- /* The effect from this source in the group makes peffect
- * redundant. Note this causes the redundancy even if the
- * elt->source_building has no effects actually in the group! */
- return TRUE;
- }
+ effect_list_iterate(plist, peffect) {
+ if (peffect->type == effect) {
+ return TRUE;
}
- } effect_group_element_list_iterate_end;
+ } effect_list_iterate_end;
+ return FALSE;
+}
+/**************************************************************************
+ Return TRUE iff any of the disabling requirements for this effect are
+ active (an effect is active if all of its enabling requirements and
+ none of its disabling ones are active).
+**************************************************************************/
+bool is_effect_disabled(enum target_type target,
+ const struct player *target_player,
+ const struct city *target_city,
+ Impr_Type_id target_building,
+ const struct tile *target_tile,
+ const struct effect *peffect)
+{
+ requirement_list_iterate(peffect->nreqs, preq) {
+ if (is_req_active(target, target_player, target_city, target_building,
+ target_tile, preq)) {
+ return TRUE;
+ }
+ } requirement_list_iterate_end;
return FALSE;
}
/**************************************************************************
- Checks the requirements of the effect to see if it is active on the
- given target. (If the requirements are not met the effect should be
- ignored.)
-**************************************************************************/
-static bool are_effect_reqs_active(enum target_type target,
- const struct player *target_player,
- const struct city *target_city,
- Impr_Type_id target_building,
- const struct tile *target_tile,
- Impr_Type_id source,
- const struct effect *peffect)
+ Return TRUE iff any of the disabling requirements for this effect are
+ active (an effect is active if all of its enabling requirements and
+ none of its disabling ones are active).
+**************************************************************************/
+static bool is_effect_enabled(enum target_type target,
+ const struct player *target_player,
+ const struct city *target_city,
+ Impr_Type_id target_building,
+ const struct tile *target_tile,
+ const struct effect *peffect)
+{
+ requirement_list_iterate(peffect->reqs, preq) {
+ if (!is_req_active(target, target_player, target_city, target_building,
+ target_tile, preq)) {
+ return FALSE;
+ }
+ } requirement_list_iterate_end;
+ return TRUE;
+}
+
+/**************************************************************************
+ Is the effect active at a certain target (player, city or building)?
+
+ This checks whether an effect's requirements are met.
+
+ target gives the type of the target
+ (player,city,building,tile) give the exact target
+ peffect gives the exact effect value
+**************************************************************************/
+static bool is_effect_active(enum target_type target,
+ const struct player *plr,
+ const struct city *pcity,
+ Impr_Type_id building,
+ const struct tile *ptile,
+ const struct effect *peffect)
{
- return is_req_active(target, target_player, target_city, target_building,
- target_tile, &peffect->req);
+ return is_effect_enabled(target, plr, pcity, building, ptile, peffect)
+ && !is_effect_disabled(target, plr, pcity, building, ptile, peffect);
}
/**************************************************************************
@@ -685,41 +619,21 @@
const struct tile *target_tile,
Impr_Type_id source, const struct effect *peffect)
{
- if (is_effect_redundant(target, target_player, target_city,
- target_building, source, peffect)) {
- return FALSE;
- }
- return are_effect_reqs_active(target, target_player, target_city,
- target_building, target_tile,
- source, peffect);
-}
-
-/**************************************************************************
- Is the effect from the source building active at a certain target (player,
- city or building)?
-
- This checks whether the source exists, whether it is made redundant by
- another element in its group, and if its requirements are met.
-
- target gives the type of the target
- (player,city,building,tile) give the exact target
- source gives the source type of the effect
- peffect gives the exact effect value
-**************************************************************************/
-static bool is_effect_active(enum target_type target,
- const struct player *plr,
- const struct city *pcity,
- Impr_Type_id building,
- const struct tile *ptile,
- Impr_Type_id source,
- const struct effect *peffect)
-{
- if (count_buildings_in_range(target, plr, pcity, building, peffect->range,
- peffect->survives, source) == 0) {
+ if (is_effect_disabled(target, target_player, target_city,
+ target_building, target_tile, peffect)) {
return FALSE;
}
- return is_effect_useful(target, plr, pcity, building,
- ptile, source, peffect);
+ requirement_list_iterate(peffect->reqs, preq) {
+ if (preq->source.type == REQ_BUILDING
+ && preq->source.value.building == source) {
+ continue;
+ }
+ if (!is_req_active(target, target_player, target_city, target_building,
+ target_tile, preq)) {
+ return FALSE;
+ }
+ } requirement_list_iterate_end;
+ return TRUE;
}
/**************************************************************************
@@ -728,58 +642,29 @@
**************************************************************************/
bool is_building_replaced(const struct city *pcity, Impr_Type_id building)
{
- bool groups_present = FALSE;
+ struct req_source source;
+ struct effect_list *plist;
- /* A building that has no effects is never redundant. */
- effect_type_vector_iterate(get_building_effect_types(building), ptype) {
- effect_list_iterate(get_building_effects(building, *ptype), peffect) {
- /* We use TARGET_BUILDING as the lowest common denominator. Note that
- * the building is its own target - but whether this is actually
- * checked depends on the range of the effect. */
- if (!is_effect_redundant(TARGET_BUILDING, city_owner(pcity), pcity,
- building, building, peffect)) {
- return FALSE;
- }
- if (peffect->group) {
- groups_present = TRUE;
- }
- } effect_list_iterate_end;
- } effect_type_vector_iterate_end;
-
- return groups_present;
-}
+ source.type = REQ_BUILDING;
+ source.value.building = building;
-/**************************************************************************
- Get the total value, for one effect type, of one source building type on
- the given target.
+ plist = get_req_source_effects(&source);
- target gives the type of the target
- (player,city,building,tile) give the exact target
- source gives the source type of the effect
- effect_type gives the effect type to be considered
-**************************************************************************/
-static int get_effect_value(enum target_type target,
- const struct player *target_player,
- const struct city *target_city,
- Impr_Type_id target_building,
- const struct tile *target_tile,
- Impr_Type_id source,
- enum effect_type effect_type)
-{
- int value = 0;
+ /* A building that has no effects is never redundant. */
+ if (!plist) {
+ return FALSE;
+ }
- /* Loop over all effects of this type provided by the given source. */
- effect_list_iterate(get_building_effects(source, effect_type), peffect) {
- /* For each effect, see if it is active. */
- if (is_effect_active(target, target_player, target_city,
- target_building, target_tile,
- source, peffect)) {
- /* And if so add on the value. */
- value += peffect->value;
+ effect_list_iterate(plist, peffect) {
+ /* We use TARGET_BUILDING as the lowest common denominator. Note that
+ * the building is its own target - but whether this is actually
+ * checked depends on the range of the effect. */
+ if (!is_effect_disabled(TARGET_BUILDING, city_owner(pcity), pcity,
+ building, NULL, peffect)) {
+ return FALSE;
}
} effect_list_iterate_end;
-
- return value;
+ return TRUE;
}
/**************************************************************************
@@ -794,7 +679,7 @@
The returned vector must be freed (building_vector_free) when the caller
is done with it.
**************************************************************************/
-static int get_target_bonus_sources(struct effect_source_vector *sources,
+static int get_target_bonus_effects(struct effect_list *plist,
enum target_type target,
const struct player *target_player,
const struct city *target_city,
@@ -804,31 +689,19 @@
{
int bonus = 0;
- if (sources) {
- effect_source_vector_init(sources);
- }
-
- /* Loop over all sources that may provide this effect. */
- building_vector_iterate(get_buildings_with_effect(effect_type), pbldg) {
- int value;
-
- /* And for each source, add on the amount of effect provided by it. */
- value = get_effect_value(target, target_player, target_city,
- target_building, target_tile,
- *pbldg, effect_type);
- bonus += value;
-
- if (sources) {
- struct effect_source e;
-
- e.building = *pbldg;
- e.effect_value = value;
+ /* Loop over all effects of this type. */
+ effect_list_iterate(get_effects(effect_type), peffect) {
+ /* For each effect, see if it is active. */
+ if (is_effect_active(target, target_player, target_city,
+ target_building, target_tile, peffect)) {
+ /* And if so add on the value. */
+ bonus += peffect->value;
- if (value != 0) {
- effect_source_vector_append(sources, &e);
+ if (plist) {
+ effect_list_append(plist, peffect);
}
}
- } building_vector_iterate_end;
+ } effect_list_iterate_end;
return bonus;
}
@@ -839,8 +712,8 @@
int get_player_bonus(const struct player *pplayer,
enum effect_type effect_type)
{
- return get_target_bonus_sources(NULL, TARGET_PLAYER,
- pplayer, NULL, B_LAST, NULL,
+ return get_target_bonus_effects(NULL, TARGET_PLAYER,
+ pplayer, NULL, B_LAST, NULL,
effect_type);
}
@@ -849,7 +722,7 @@
**************************************************************************/
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
{
- return get_target_bonus_sources(NULL, TARGET_CITY,
+ return get_target_bonus_effects(NULL, TARGET_CITY,
city_owner(pcity), pcity, B_LAST, NULL,
effect_type);
}
@@ -860,8 +733,8 @@
int get_city_tile_bonus(const struct city *pcity, const struct tile *ptile,
enum effect_type effect_type)
{
- return get_target_bonus_sources(NULL, TARGET_CITY,
- city_owner(pcity), pcity, B_LAST, ptile,
+ return get_target_bonus_effects(NULL, TARGET_CITY,
+ city_owner(pcity), pcity, B_LAST, ptile,
effect_type);
}
@@ -871,8 +744,8 @@
int get_building_bonus(const struct city *pcity, Impr_Type_id id,
enum effect_type effect_type)
{
- return get_target_bonus_sources(NULL, TARGET_BUILDING,
- city_owner(pcity), pcity, id, NULL,
+ return get_target_bonus_effects(NULL, TARGET_CITY,
+ city_owner(pcity), pcity, id, NULL,
effect_type);
}
@@ -882,10 +755,11 @@
The returned vector must be freed (building_vector_free) when the caller
is done with it.
**************************************************************************/
-int get_player_bonus_sources(struct effect_source_vector *sources,
- const struct player *pplayer, enum effect_type effect_type)
+int get_player_bonus_effects(struct effect_list *plist,
+ const struct player *pplayer,
+ enum effect_type effect_type)
{
- return get_target_bonus_sources(sources, TARGET_PLAYER,
+ return get_target_bonus_effects(plist, TARGET_PLAYER,
pplayer, NULL, B_LAST, NULL,
effect_type);
}
@@ -896,10 +770,11 @@
The returned vector must be freed (building_vector_free) when the caller
is done with it.
**************************************************************************/
-int get_city_bonus_sources(struct effect_source_vector *sources,
- const struct city *pcity, enum effect_type effect_type)
+int get_city_bonus_effects(struct effect_list *plist,
+ const struct city *pcity,
+ enum effect_type effect_type)
{
- return get_target_bonus_sources(sources, TARGET_CITY,
+ return get_target_bonus_effects(plist, TARGET_CITY,
city_owner(pcity), pcity, B_LAST, NULL,
effect_type);
}
@@ -914,19 +789,64 @@
enum effect_type effect_type)
{
if (!pcity->is_building_unit) {
- Impr_Type_id bldg = pcity->currently_building;
+ Impr_Type_id id = pcity->currently_building;
int power = 0;
- effect_list_iterate(get_building_effects(bldg, effect_type), peffect) {
+ struct req_source source = {
+ .type = REQ_BUILDING,
+ .value.building = id
+ };
+ struct effect_list *plist = get_req_source_effects(&source);
+
+ effect_list_iterate(plist, peffect) {
+ if (peffect->type != effect_type) {
+ continue;
+ }
if (is_effect_useful(TARGET_BUILDING, city_owner(pcity),
- pcity, bldg, NULL, bldg, peffect)) {
+ pcity, id, NULL, id, peffect)) {
power += peffect->value;
}
} effect_list_iterate_end;
return power;
}
-
return 0;
}
+/**************************************************************************
+**************************************************************************/
+void get_effect_req_text(struct effect *peffect, char *buf, size_t buf_len)
+{
+ buf[0] = '\0';
+
+ requirement_list_iterate(peffect->reqs, preq) {
+ struct req_source *psource = &preq->source;
+
+ if (buf[0] != '\0') {
+ mystrlcat(buf, "+", buf_len);
+ }
+
+ switch (psource->type) {
+ case REQ_NONE:
+ break;
+ case REQ_TECH:
+ mystrlcat(buf, advances[psource->value.tech].name, buf_len);
+ break;
+ case REQ_GOV:
+ mystrlcat(buf, get_government_name(psource->value.gov), buf_len);
+ break;
+ case REQ_BUILDING:
+ mystrlcat(buf, get_improvement_name(psource->value.building), buf_len);
+ break;
+ case REQ_SPECIAL:
+ mystrlcat(buf, get_special_name(psource->value.special), buf_len);
+ break;
+ case REQ_TERRAIN:
+ mystrlcat(buf, get_terrain_name(psource->value.terrain), buf_len);
+ break;
+ case REQ_LAST:
+ break;
+ }
+ } requirement_list_iterate_end;
+}
+
Index: common/effects.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/effects.h,v
retrieving revision 1.13
diff -u -r1.13 effects.h
--- common/effects.h 17 Dec 2004 08:21:20 -0000 1.13
+++ common/effects.h 31 Jan 2005 18:20:56 -0000
@@ -112,53 +112,27 @@
enum effect_type effect_type_from_str(const char *str);
const char *effect_type_name(enum effect_type effect_type);
-/* A building_vector is an array of building types. */
-#define SPECVEC_TAG building
-#define SPECVEC_TYPE Impr_Type_id
-#include "specvec.h"
-#define building_vector_iterate(vector, pbldg) \
- TYPED_VECTOR_ITERATE(Impr_Type_id, vector, pbldg)
-#define building_vector_iterate_end VECTOR_ITERATE_END
-
-/* An effect_type_vector is an array of effect types. */
-#define SPECVEC_TAG effect_type
-#define SPECVEC_TYPE enum effect_type
-#include "specvec.h"
-#define effect_type_vector_iterate(vector, ptype) \
- TYPED_VECTOR_ITERATE(enum effect_type, vector, ptype)
-#define effect_type_vector_iterate_end VECTOR_ITERATE_END
-
-struct effect_group;
-
/* An effect is provided by a source. If the source is present, and the
* other conditions (described below) are met, the effect will be active.
- * Note the difference between effect and effect_type. The effect doesn't
- * give an effect_type because all effects in an effect_vector will be of
- * the same type. */
+ * Note the difference between effect and effect_type. */
struct effect {
- /* The range the effect applies to, relative to the source. For instance
- * if the source is a building an effect with range "city" will apply to
- * everything in that city. */
- enum req_range range;
+ enum effect_type type;
/* The "value" of the effect. The meaning of this varies between
* effects. When get_xxx_bonus() is called the value of all applicable
* effects will be summed up. */
int value;
- /* The group this effect is in. If more than one source in the group
- * provides the effect, only one will be active. */
- struct effect_group *group;
-
- /* If true, this effect will survive even if its source is destroyed. */
- bool survives;
-
- /* An effect can have a single requirement. The effect will only be
- * active if this requirement is met. The req is one of several types. */
- struct requirement req;
+ /* An effect can have multiple requirements. The effect will only be
+ * active if all of these requirement are met. */
+ struct requirement_list *reqs;
+
+ /* An effect can have multiple negated requirements. The effect will
+ * only be active if none of these requirements are met. */
+ struct requirement_list *nreqs;
};
-/* An effect_vector is an array of effects. */
+/* An effect_list is a list of effects. */
#define SPECLIST_TAG effect
#define SPECLIST_TYPE struct effect
#include "speclist.h"
@@ -166,35 +140,22 @@
TYPED_LIST_ITERATE(struct effect, effect_list, peffect)
#define effect_list_iterate_end LIST_ITERATE_END
-/* This struct contains a source building along with the effect value. It is
- * primarily useful for get_city_bonus_sources(). */
-struct effect_source {
- Impr_Type_id building;
- int effect_value;
-};
-#define SPECVEC_TAG effect_source
-#define SPECVEC_TYPE struct effect_source
-#include "specvec.h"
-#define effect_source_vector_iterate(vector, psource) \
- TYPED_VECTOR_ITERATE(struct effect_source, vector, psource)
-#define effect_source_vector_iterate_end VECTOR_ITERATE_END
+struct effect *effect_new(enum effect_type type, int value);
+void effect_req_append(struct effect *peffect, bool neg,
+ struct requirement *preq);
+
+void get_effect_req_text(struct effect *peffect, char *buf, size_t buf_len);
/* ruleset cache creation and communication functions */
+struct packet_ruleset_effect;
+struct packet_ruleset_effect_req;
+
void ruleset_cache_init(void);
void ruleset_cache_free(void);
-void ruleset_cache_add(Impr_Type_id source, enum effect_type effect_type,
- enum req_range range, bool survives, int eff_value,
- struct requirement *req,
- int group_id);
+void recv_ruleset_effect(struct packet_ruleset_effect *packet);
+void recv_ruleset_effect_req(struct packet_ruleset_effect_req *packet);
void send_ruleset_cache(struct conn_list *dest);
-/* equivalent effect group */
-struct effect_group *effect_group_new(const char *name);
-void effect_group_add_element(struct effect_group *group,
- Impr_Type_id source_building,
- enum req_range range, bool survives);
-int find_effect_group_id(const char *name);
-
bool is_effect_useful(enum target_type target,
const struct player *target_player,
const struct city *target_pcity,
@@ -213,13 +174,17 @@
enum effect_type effect_type);
/* miscellaneous auxiliary effects functions */
-struct effect_list *get_building_effects(Impr_Type_id building,
- enum effect_type effect_type);
-struct effect_type_vector *get_building_effect_types(Impr_Type_id building);
+struct effect_list *get_req_source_effects(struct req_source *psource);
+bool is_effect_disabled(enum target_type target,
+ const struct player *target_player,
+ const struct city *target_city,
+ Impr_Type_id target_building,
+ const struct tile *target_tile,
+ const struct effect *peffect);
-int get_player_bonus_sources(struct effect_source_vector *sources,
+int get_player_bonus_effects(struct effect_list *plist,
const struct player *pplayer, enum effect_type effect_type);
-int get_city_bonus_sources(struct effect_source_vector *sources,
+int get_city_bonus_effects(struct effect_list *plist,
const struct city *pcity, enum effect_type effect_type);
bool building_has_effect(Impr_Type_id building,
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.91
diff -u -r1.91 packets.def
--- common/packets.def 29 Jan 2005 17:58:18 -0000 1.91
+++ common/packets.def 31 Jan 2005 18:20:56 -0000
@@ -181,7 +181,7 @@
type DIRECTION = uint8(enum direction8)
type ORDERS = uint8(enum unit_orders)
type SSET_TYPE = uint8(enum sset_type)
-type REQ_TYPE = uint8(enum req_type)
+type REQ_TYPE = uint8(enum req_source_type)
type REQ_RANGE = uint8(enum req_range)
type EFFECT_TYPE = uint8(enum effect_type)
@@ -1266,23 +1266,19 @@
/************** Effects hash packets **********************/
-PACKET_RULESET_CACHE_GROUP=120;sc,lsend
- STRING name[MAX_LEN_NAME];
-
- UINT8 num_elements;
- IMPROVEMENT source_buildings[255:num_elements];
- REQ_RANGE ranges[255:num_elements];
- BOOL survives[255:num_elements];
+PACKET_RULESET_EFFECT=122;sc,lsend
+ EFFECT_TYPE effect_type;
+ SINT32 effect_value;
end
-PACKET_RULESET_CACHE_EFFECT=121;sc,lsend
- IMPROVEMENT id;
- EFFECT_TYPE effect_type;
+PACKET_RULESET_EFFECT_REQ=123;sc,lsend
+ UINT32 effect_id;
+ BOOL neg;
+
+ REQ_TYPE source_type;
+ SINT32 source_value;
+
REQ_RANGE range;
BOOL survives;
- SINT32 eff_value;
- REQ_TYPE req_type;
- SINT32 req_value;
- SINT32 group_id;
end
Index: common/requirements.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.c,v
retrieving revision 1.4
diff -u -r1.4 requirements.c
--- common/requirements.c 19 Dec 2004 16:47:09 -0000 1.4
+++ common/requirements.c 31 Jan 2005 18:20:56 -0000
@@ -25,9 +25,9 @@
#include "map.h"
#include "requirements.h"
-/* Names of requirement types. These must correspond to enum req_type in
+/* Names of source types. These must correspond to enum req_source_type in
* requirements.h. Do not change these unless you know what you're doing! */
-static const char *req_type_names[] = {
+static const char *req_source_type_names[] = {
"None",
"Tech",
"Gov",
@@ -67,86 +67,63 @@
return REQ_RANGE_LAST;
}
-/****************************************************************************
- Parse a requirement type and value string into a requrement structure.
- Returns REQ_LAST on error. Passing in a NULL type is considered REQ_NONE
- (not an error).
+/**************************************************************************
+ Parse a requirement type and value string into a requirement source
+ structure. Passing in a NULL type is considered REQ_NONE (not an error).
Pass this some values like "Building", "Factory".
-****************************************************************************/
-struct requirement req_from_str(const char *type,
- const char *range, bool survives,
- const char *value)
+**************************************************************************/
+struct req_source req_source_from_str(const char *type, const char *value)
{
- struct requirement req;
+ struct req_source source;
const struct government *pgov;
- assert(ARRAY_SIZE(req_type_names) == REQ_LAST);
+ assert(ARRAY_SIZE(req_source_type_names) == REQ_LAST);
if (type) {
- for (req.type = 0; req.type < ARRAY_SIZE(req_type_names); req.type++) {
- if (0 == mystrcasecmp(req_type_names[req.type], type)) {
+ for (source.type = 0;
+ source.type < ARRAY_SIZE(req_source_type_names);
+ source.type++) {
+ if (0 == mystrcasecmp(req_source_type_names[source.type], type)) {
break;
}
}
} else {
- req.type = REQ_NONE;
- }
-
- /* Scan the range string to find the range. If no range is given a
- * default fallback is used rather than giving an error. */
- req.range = req_range_from_str(range);
- if (req.range == REQ_RANGE_LAST) {
- switch (req.type) {
- case REQ_NONE:
- case REQ_LAST:
- break;
- case REQ_BUILDING:
- case REQ_SPECIAL:
- case REQ_TERRAIN:
- req.range = REQ_RANGE_CITY;
- break;
- case REQ_GOV:
- case REQ_TECH:
- req.range = REQ_RANGE_PLAYER;
- break;
- }
+ source.type = REQ_NONE;
}
- req.survives = survives;
-
- /* Finally scan the value string based on the type of the req. */
- switch (req.type) {
+ /* Finally scan the value string based on the type of the source. */
+ switch (source.type) {
case REQ_NONE:
- return req;
+ return source;
case REQ_TECH:
- req.value.tech = find_tech_by_name(value);
- if (req.value.tech != A_LAST) {
- return req;
+ source.value.tech = find_tech_by_name(value);
+ if (source.value.tech != A_LAST) {
+ return source;
}
break;
case REQ_GOV:
pgov = find_government_by_name(value);
if (pgov != NULL) {
- req.value.gov = pgov->index;
- return req;
+ source.value.gov = pgov->index;
+ return source;
}
break;
case REQ_BUILDING:
- req.value.building = find_improvement_by_name(value);
- if (req.value.building != B_LAST) {
- return req;
+ source.value.building = find_improvement_by_name(value);
+ if (source.value.building != B_LAST) {
+ return source;
}
break;
case REQ_SPECIAL:
- req.value.special = get_special_by_name(value);
- if (req.value.special != S_NO_SPECIAL) {
- return req;
+ source.value.special = get_special_by_name(value);
+ if (source.value.special != S_NO_SPECIAL) {
+ return source;
}
break;
case REQ_TERRAIN:
- req.value.terrain = get_terrain_by_name(value);
- if (req.value.terrain != T_UNKNOWN) {
- return req;
+ source.value.terrain = get_terrain_by_name(value);
+ if (source.value.terrain != T_UNKNOWN) {
+ return source;
}
break;
case REQ_LAST:
@@ -154,39 +131,74 @@
}
/* If we reach here there's been an error. */
- req.type = REQ_LAST;
- return req;
+ source.type = REQ_LAST;
+ return source;
}
-/****************************************************************************
- Return the value of a req as a serializable integer. This is the opposite
- of req_set_value.
-****************************************************************************/
-void req_get_values(struct requirement *req,
- int *type, int *range, bool *survives, int *value)
+/**************************************************************************
+ Parse some integer values into a req source. This is for serialization
+ of req sources and is the opposite of req_source_get_values().
+**************************************************************************/
+struct req_source req_source_from_values(int type, int value)
{
- *type = req->type;
- *range = req->range;
- *survives = req->survives;
+ struct req_source source;
+
+ source.type = type;
+
+ switch (source.type) {
+ case REQ_NONE:
+ return source;
+ case REQ_TECH:
+ source.value.tech = value;
+ return source;
+ case REQ_GOV:
+ source.value.gov = value;
+ return source;
+ case REQ_BUILDING:
+ source.value.building = value;
+ return source;
+ case REQ_SPECIAL:
+ source.value.special = value;
+ return source;
+ case REQ_TERRAIN:
+ source.value.terrain = value;
+ return source;
+ case REQ_LAST:
+ return source;
+ }
+
+ source.type = REQ_LAST;
+ assert(0);
+ return source;
+}
+
+/**************************************************************************
+ Look at a req source and return some integer values describing it. This
+ is for serialization of req sources and is the opposite of
+ req_source_from_values().
+**************************************************************************/
+void req_source_get_values(struct req_source *source, int *type, int *value)
+{
+ *type = source->type;
- switch (req->type) {
+ switch (source->type) {
case REQ_NONE:
*value = 0;
return;
case REQ_TECH:
- *value = req->value.tech;
+ *value = source->value.tech;
return;
case REQ_GOV:
- *value = req->value.gov;
+ *value = source->value.gov;
return;
case REQ_BUILDING:
- *value = req->value.building;
+ *value = source->value.building;
return;
case REQ_SPECIAL:
- *value = req->value.special;
+ *value = source->value.special;
return;
case REQ_TERRAIN:
- *value = req->value.terrain;
+ *value = source->value.terrain;
return;
case REQ_LAST:
break;
@@ -197,6 +209,45 @@
}
/****************************************************************************
+ Parse a requirement type and value string into a requrement structure.
+ Returns REQ_LAST on error. Passing in a NULL type is considered REQ_NONE
+ (not an error).
+
+ Pass this some values like "Building", "Factory".
+****************************************************************************/
+struct requirement req_from_str(const char *type,
+ const char *range, bool survives,
+ const char *value)
+{
+ struct requirement req;
+
+ req.source = req_source_from_str(type, value);
+
+ /* Scan the range string to find the range. If no range is given a
+ * default fallback is used rather than giving an error. */
+ req.range = req_range_from_str(range);
+ if (req.range == REQ_RANGE_LAST) {
+ switch (req.source.type) {
+ case REQ_NONE:
+ case REQ_LAST:
+ break;
+ case REQ_BUILDING:
+ case REQ_SPECIAL:
+ case REQ_TERRAIN:
+ req.range = REQ_RANGE_CITY;
+ break;
+ case REQ_GOV:
+ case REQ_TECH:
+ req.range = REQ_RANGE_PLAYER;
+ break;
+ }
+ }
+
+ req.survives = survives;
+ return req;
+}
+
+/****************************************************************************
Set the values of a req from serializable integers. This is the opposite
of req_get_values.
****************************************************************************/
@@ -205,38 +256,25 @@
{
struct requirement req;
- req.type = type;
+ req.source = req_source_from_values(type, value);
req.range = range;
req.survives = survives;
-
- switch (req.type) {
- case REQ_NONE:
- return req;
- case REQ_TECH:
- req.value.tech = value;
- return req;
- case REQ_GOV:
- req.value.gov = value;
- return req;
- case REQ_BUILDING:
- req.value.building = value;
- return req;
- case REQ_SPECIAL:
- req.value.special = value;
- return req;
- case REQ_TERRAIN:
- req.value.terrain = value;
- return req;
- case REQ_LAST:
- return req;
- }
-
- req.type = REQ_LAST;
- assert(0);
return req;
}
/****************************************************************************
+ Return the value of a req as a serializable integer. This is the opposite
+ of req_set_value.
+****************************************************************************/
+void req_get_values(struct requirement *req,
+ int *type, int *range, bool *survives, int *value)
+{
+ req_source_get_values(&req->source, type, value);
+ *range = req->range;
+ *survives = req->survives;
+}
+
+/****************************************************************************
Is this target possible for the range involved?
For instance a city-ranged requirement can't have a player as it's target.
@@ -452,29 +490,34 @@
* have a REQ_SPECIAL or REQ_TERRAIN may often be passed to this function
* with a city as their target. In this case the requirement is simply
* not met. */
- switch (req->type) {
+ switch (req->source.type) {
case REQ_NONE:
return TRUE;
case REQ_TECH:
/* The requirement is filled if the player owns the tech. */
return (target_player
- && get_invention(target_player, req->value.tech) == TECH_KNOWN);
+ && get_invention(target_player,
+ req->source.value.tech) == TECH_KNOWN);
case REQ_GOV:
/* The requirement is filled if the player is using the government. */
- return target_player && (target_player->government == req->value.gov);
+ return (target_player
+ && (target_player->government == req->source.value.gov));
case REQ_BUILDING:
/* The requirement is filled if there's at least one of the building
* in the city. (This is a slightly nonstandard use of
* count_sources_in_range.) */
return (count_buildings_in_range(target, target_player, target_city,
- target_building, REQ_RANGE_CITY, FALSE,
- req->value.building) > 0);
+ target_building,
+ req->range, req->survives,
+ req->source.value.building) > 0);
case REQ_SPECIAL:
/* The requirement is filled if the tile has the special. */
- return target_tile && tile_has_special(target_tile, req->value.special);
+ return (target_tile
+ && tile_has_special(target_tile, req->source.value.special));
case REQ_TERRAIN:
/* The requirement is filled if the tile has the terrain. */
- return target_tile && (target_tile->terrain == req->value.terrain);
+ return (target_tile
+ && (target_tile->terrain == req->source.value.terrain));
case REQ_LAST:
break;
}
Index: common/requirements.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.h,v
retrieving revision 1.2
diff -u -r1.2 requirements.h
--- common/requirements.h 17 Dec 2004 08:21:20 -0000 1.2
+++ common/requirements.h 31 Jan 2005 18:20:56 -0000
@@ -17,9 +17,9 @@
#include "fc_types.h"
#include "tech.h"
-/* The type of a requirement. This must correspond to req_type_names[]
+/* The type of a requirement source. This must correspond to req_type_names[]
* in requirements.c. */
-enum req_type {
+enum req_source_type {
REQ_NONE,
REQ_TECH,
REQ_GOV,
@@ -49,25 +49,41 @@
TARGET_BUILDING
};
+/* A requirement source. */
+struct req_source {
+ enum req_source_type type; /* source type */
+
+ union {
+ Tech_Type_id tech; /* source tech */
+ int gov; /* source government */
+ Impr_Type_id building; /* source building */
+ enum tile_special_type special; /* source special */
+ Terrain_type_id terrain; /* source terrain type */
+ } value; /* source value */
+};
+
/* A requirement. This requirement is basically a conditional; it may or
* may not be active on a target. If it is active then something happens.
* For instance units and buildings have requirements to be built, techs
* have requirements to be researched, and effects have requirements to be
* active. */
struct requirement {
- enum req_type type; /* requirement type */
+ struct req_source source; /* requirement source */
enum req_range range; /* requirement range */
bool survives; /* set if destroyed sources satisfy the req*/
-
- union {
- Tech_Type_id tech; /* requirement tech */
- int gov; /* requirement government */
- Impr_Type_id building; /* requirement building */
- enum tile_special_type special; /* requirement special */
- Terrain_type_id terrain; /* requirement terrain type */
- } value; /* requirement value */
};
+#define SPECLIST_TAG requirement
+#define SPECLIST_TYPE struct requirement
+#include "speclist.h"
+#define requirement_list_iterate(req_list, preq) \
+ TYPED_LIST_ITERATE(struct requirement, req_list, preq)
+#define requirement_list_iterate_end LIST_ITERATE_END
+
+struct req_source req_source_from_str(const char *type, const char *value);
+struct req_source req_source_from_values(int type, int value);
+void req_source_get_values(struct req_source *source, int *type, int *value);
+
enum req_range req_range_from_str(const char *str);
struct requirement req_from_str(const char *type, const char *range,
bool survives, const char *value);
Index: data/civ1/effects.ruleset
===================================================================
RCS file: data/civ1/effects.ruleset
diff -N data/civ1/effects.ruleset
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ data/civ1/effects.ruleset 31 Jan 2005 18:20:56 -0000
@@ -0,0 +1,670 @@
+; Modifying this file:
+; You should not modify this file except to make bugfixes or
+; for other "maintenance". If you want to make custom changes,
+; you should create a new datadir subdirectory and copy this file
+; into that directory, and then modify that copy. Then use the
+; command "rulesetdir <mysubdir>" in the server to have freeciv
+; use your new customized file.
+
+; Note that the freeciv AI may not cope well with anything more
+; than minor changes.
+
+[datafile]
+description="Civ1 effects data for Freeciv (approximate)"
+options="1.0"
+
+; /* <-- avoid gettext warnings
+; */ <-- avoid gettext warnings
+
+[effect_aqueduct]
+name = "Size_Unlimit"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Aqueduct", "City"
+ }
+
+[effect_bank]
+name = "Tax_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ "Building", "Bank", "City"
+ }
+
+[effect_bank_1]
+name = "Luxury_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ "Building", "Bank", "City"
+ }
+
+[effect_barracks]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks", "City"
+ }
+
+[effect_barracks_1]
+name = "Sea_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks", "City"
+ }
+
+[effect_barracks_2]
+name = "Air_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks", "City"
+ }
+
+[effect_barracks_ii]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks II", "City"
+ }
+
+[effect_barracks_ii_1]
+name = "Sea_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks II", "City"
+ }
+
+[effect_barracks_ii_2]
+name = "Air_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks II", "City"
+ }
+
+[effect_barracks_iii]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks III", "City"
+ }
+
+[effect_barracks_iii_1]
+name = "Sea_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks III", "City"
+ }
+
+[effect_barracks_iii_2]
+name = "Air_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks III", "City"
+ }
+
+[effect_cathedral]
+name = "Make_Content"
+value = 4
+reqs =
+ { "type", "name", "range"
+ "Building", "Cathedral", "City"
+ }
+
+[effect_city_walls]
+name = "Land_Defend"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "City Walls", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
+[effect_city_walls_1]
+name = "Sea_Defend"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "City Walls", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
+[effect_city_walls_2]
+name = "Unit_No_Lose_Pop"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "City Walls", "City"
+ }
+
+[effect_colosseum]
+name = "Make_Content"
+value = 3
+reqs =
+ { "type", "name", "range"
+ "Building", "Colosseum", "City"
+ }
+
+[effect_courthouse]
+name = "Corrupt_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Courthouse", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_courthouse_1]
+name = "Waste_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Courthouse", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_factory]
+name = "Prod_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ }
+
+[effect_granary]
+name = "Growth_Food"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Granary", "City"
+ }
+
+[effect_hydro_plant]
+name = "Prod_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Hydro Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ }
+
+[effect_hydro_plant_1]
+name = "Pollu_Prod_Pct"
+value = -50
+reqs =
+ { "type", "name", "range"
+ "Building", "Hydro Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ }
+
+[effect_library]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ }
+
+[effect_marketplace]
+name = "Tax_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ }
+
+[effect_marketplace_1]
+name = "Luxury_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ }
+
+[effect_mass_transit]
+name = "Pollu_Pop_Pct"
+value = -100
+reqs =
+ { "type", "name", "range"
+ "Building", "Mass Transit", "City"
+ }
+
+[effect_mfg_plant]
+name = "Prod_Bonus"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ }
+
+[effect_nuclear_plant]
+name = "Prod_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Nuclear Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_nuclear_plant_1]
+name = "Pollu_Prod_Pct"
+value = -50
+reqs =
+ { "type", "name", "range"
+ "Building", "Nuclear Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_palace]
+name = "Corrupt_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_1]
+name = "Waste_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_2]
+name = "Spy_Resistant"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_3]
+name = "No_Incite"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_4]
+name = "Capital_City"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_power_plant]
+name = "Prod_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Power Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ "Building", "Hydro Plant", "City"
+ }
+
+[effect_recycling_center]
+name = "Pollu_Prod_Pct"
+value = -66
+reqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ }
+
+[effect_sdi_defense]
+name = "Nuke_Proof"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "SDI Defense", "City"
+ }
+
+[effect_space_component]
+name = "SS_Component"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Space Component", "City"
+ }
+
+[effect_space_module]
+name = "SS_Module"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Space Module", "City"
+ }
+
+[effect_space_structural]
+name = "SS_Structural"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Space Structural", "City"
+ }
+
+[effect_temple]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Temple", "City"
+ }
+
+[effect_temple_1]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Mysticism", "Player"
+ "Building", "Temple", "City"
+ }
+
+[effect_university]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ "Building", "University", "City"
+ }
+
+[effect_apollo_program]
+name = "Reveal_Cities"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Apollo Program", "Player"
+ }
+
+[effect_apollo_program_1]
+name = "Enable_Space"
+value = 1
+reqs =
+ { "type", "name", "range", "survives"
+ "Building", "Apollo Program", "World", 1
+ }
+
+[effect_colossus]
+name = "Trade_Inc_Tile"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Colossus", "City"
+ }
+
+[effect_copernicus_observatory]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ "Building", "Copernicus' Observatory", "City"
+ }
+
+[effect_copernicus_observatory_1]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "University", "City"
+ "Building", "Copernicus' Observatory", "City"
+ }
+
+[effect_copernicus_observatory_2]
+name = "Science_Bonus"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "Copernicus' Observatory", "City"
+ }
+
+[effect_cure_for_cancer]
+name = "Force_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Cure For Cancer", "Player"
+ }
+
+[effect_darwins_voyage]
+name = "Give_Imm_Tech"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Darwin's Voyage", "Player"
+ }
+
+[effect_great_library]
+name = "Tech_Parasite"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Library", "Player"
+ }
+
+[effect_great_wall]
+name = "Land_Defend"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
+[effect_great_wall_1]
+name = "Sea_Defend"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
+[effect_hanging_gardens]
+name = "Make_Happy"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Hanging Gardens", "Player"
+ }
+
+[effect_hoover_dam]
+name = "Prod_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Continent"
+ }
+
+[effect_hoover_dam_1]
+name = "Pollu_Prod_Pct"
+value = -50
+reqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Continent"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ }
+
+[effect_isaac_newtons_college]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ "Building", "Isaac Newton's College", "City"
+ }
+
+[effect_isaac_newtons_college_1]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "University", "City"
+ "Building", "Isaac Newton's College", "Player"
+ }
+
+[effect_js_bachs_cathedral]
+name = "Force_Content"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "J.S. Bach's Cathedral", "Continent"
+ }
+
+[effect_lighthouse]
+name = "Sea_Move"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Lighthouse", "Player"
+ }
+
+[effect_magellans_expedition]
+name = "Sea_Move"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Magellan's Expedition", "Player"
+ }
+
+[effect_manhattan_project]
+name = "Enable_Nuke"
+value = 1
+reqs =
+ { "type", "name", "range", "survives"
+ "Building", "Manhattan Project", "World", 1
+ }
+
+[effect_michelangelos_chapel]
+name = "Make_Content"
+value = 4
+reqs =
+ { "type", "name", "range"
+ "Building", "Cathedral", "City"
+ "Building", "Michelangelo's Chapel", "City"
+ }
+
+[effect_oracle]
+name = "Make_Content"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Temple", "City"
+ "Building", "Oracle", "Player"
+ }
+
+[effect_pyramids]
+name = "Any_Government"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Pyramids", "Player"
+ }
+
+[effect_pyramids_1]
+name = "No_Anarchy"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Pyramids", "Player"
+ }
+
+[effect_seti_program]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "SETI Program", "Player"
+ }
+
+[effect_shakespeares_theatre]
+name = "No_Unhappy"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Shakespeare's Theatre", "City"
+ }
+
+[effect_united_nations]
+name = "Any_Government"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "United Nations", "Player"
+ }
+
+[effect_united_nations_1]
+name = "No_Anarchy"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "United Nations", "Player"
+ }
+
+[effect_womens_suffrage]
+name = "Make_Content_Mil_Per"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Women's Suffrage", "Player"
+ }
+
+[effect_capitalization]
+name = "Prod_To_Gold"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Capitalization", "City"
+ }
+
Index: data/civ2/effects.ruleset
===================================================================
RCS file: data/civ2/effects.ruleset
diff -N data/civ2/effects.ruleset
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ data/civ2/effects.ruleset 31 Jan 2005 18:20:56 -0000
@@ -0,0 +1,980 @@
+; Modifying this file:
+; You should not modify this file except to make bugfixes or
+; for other "maintenance". If you want to make custom changes,
+; you should create a new datadir subdirectory and copy this file
+; into that directory, and then modify that copy. Then use the
+; command "rulesetdir <mysubdir>" in the server to have freeciv
+; use your new customized file.
+
+; Note that the freeciv AI may not cope well with anything more
+; than minor changes.
+
+[datafile]
+description="Civ2 effects data for Freeciv (incomplete)"
+options="1.0"
+
+; /* <-- avoid gettext warnings
+; */ <-- avoid gettext warnings
+
+[effect_airport]
+name = "Air_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Airport", "City"
+ }
+
+[effect_airport_1]
+name = "Air_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Airport", "City"
+ }
+
+[effect_airport_2]
+name = "Airlift"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Airport", "City"
+ }
+
+[effect_aqueduct]
+name = "Size_Adj"
+value = 4
+reqs =
+ { "type", "name", "range"
+ "Building", "Aqueduct", "City"
+ }
+
+[effect_bank]
+name = "Tax_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ "Building", "Bank", "City"
+ }
+
+[effect_bank_1]
+name = "Luxury_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ "Building", "Bank", "City"
+ }
+
+[effect_barracks]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks", "City"
+ }
+
+[effect_barracks_1]
+name = "Land_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks", "City"
+ }
+
+[effect_barracks_ii]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks II", "City"
+ }
+
+[effect_barracks_ii_1]
+name = "Land_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks II", "City"
+ }
+
+[effect_barracks_iii]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks III", "City"
+ }
+
+[effect_barracks_iii_1]
+name = "Land_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks III", "City"
+ }
+
+[effect_cathedral]
+name = "Make_Content"
+value = 3
+reqs =
+ { "type", "name", "range"
+ "Building", "Cathedral", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_cathedral_1]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Theology", "Player"
+ "Building", "Cathedral", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_cathedral_2]
+name = "Make_Content"
+value = -1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Communism", "Player"
+ "Building", "Cathedral", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_city_walls]
+name = "Land_Defend"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "City Walls", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
+[effect_city_walls_1]
+name = "Unit_No_Lose_Pop"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "City Walls", "City"
+ }
+
+[effect_coastal_defense]
+name = "Sea_Defend"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "Coastal Defense", "City"
+ }
+
+[effect_colosseum]
+name = "Make_Content"
+value = 3
+reqs =
+ { "type", "name", "range"
+ "Building", "Colosseum", "City"
+ }
+
+[effect_colosseum_1]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Electricity", "Player"
+ "Building", "Colosseum", "City"
+ }
+
+[effect_courthouse]
+name = "Corrupt_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Courthouse", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_courthouse_1]
+name = "Waste_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Courthouse", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_courthouse_2]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Gov", "Democracy", "Player"
+ "Building", "Courthouse", "City"
+ }
+
+[effect_courthouse_3]
+name = "Incite_Dist_Pct"
+value = 75
+reqs =
+ { "type", "name", "range"
+ "Building", "Courthouse", "City"
+ }
+
+[effect_factory]
+name = "Prod_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ }
+
+[effect_granary]
+name = "Growth_Food"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Granary", "City"
+ }
+
+[effect_harbour]
+name = "Food_Add_Tile"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Terrain", "Ocean", "City"
+ "Building", "Harbour", "City"
+ }
+
+[effect_hydro_plant]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Hydro Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ }
+
+[effect_hydro_plant_1]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Hydro Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ }
+
+[effect_hydro_plant_2]
+name = "Pollu_Prod_Pct"
+value = -50
+reqs =
+ { "type", "name", "range"
+ "Building", "Hydro Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ }
+
+[effect_library]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ }
+
+[effect_marketplace]
+name = "Tax_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ }
+
+[effect_marketplace_1]
+name = "Luxury_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ }
+
+[effect_mass_transit]
+name = "Pollu_Pop_Pct"
+value = -100
+reqs =
+ { "type", "name", "range"
+ "Building", "Mass Transit", "City"
+ }
+
+[effect_mfg_plant]
+name = "Prod_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Mfg. Plant", "City"
+ }
+
+[effect_nuclear_plant]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Nuclear Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_nuclear_plant_1]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Nuclear Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_nuclear_plant_2]
+name = "Pollu_Prod_Pct"
+value = -50
+reqs =
+ { "type", "name", "range"
+ "Building", "Nuclear Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_offshore_platform]
+name = "Prod_Add_Tile"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Terrain", "Ocean", "City"
+ "Building", "Offshore Platform", "City"
+ }
+
+[effect_palace]
+name = "Corrupt_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_1]
+name = "Waste_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_2]
+name = "Spy_Resistant"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_3]
+name = "No_Incite"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_4]
+name = "Capital_City"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_police_station]
+name = "Make_Content_Mil"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Gov", "Republic", "Player"
+ "Building", "Police Station", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Women's Suffrage", "Player"
+ }
+
+[effect_police_station_1]
+name = "Make_Content_Mil"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Gov", "Democracy", "Player"
+ "Building", "Police Station", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Women's Suffrage", "Player"
+ }
+
+[effect_port_facility]
+name = "Sea_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Port Facility", "City"
+ }
+
+[effect_port_facility_1]
+name = "Sea_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Port Facility", "City"
+ }
+
+[effect_power_plant]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Power Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ "Building", "Hydro Plant", "City"
+ }
+
+[effect_power_plant_1]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Power Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ "Building", "Hydro Plant", "City"
+ }
+
+[effect_recycling_center]
+name = "Pollu_Prod_Pct"
+value = -66
+reqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ }
+
+[effect_research_lab]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ "Building", "Research Lab", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "SETI Program", "Player"
+ }
+
+[effect_sam_battery]
+name = "Air_Defend"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "SAM Battery", "City"
+ }
+
+[effect_sdi_defense]
+name = "Nuke_Proof"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "SDI Defense", "City"
+ }
+
+[effect_sdi_defense_1]
+name = "Missile_Defend"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "SDI Defense", "City"
+ }
+
+[effect_sewer_system]
+name = "Size_Unlimit"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Aqueduct", "City"
+ "Building", "Sewer System", "City"
+ }
+
+[effect_space_component]
+name = "SS_Component"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Space Component", "City"
+ }
+
+[effect_space_module]
+name = "SS_Module"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Space Module", "City"
+ }
+
+[effect_space_structural]
+name = "SS_Structural"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Space Structural", "City"
+ }
+
+[effect_stock_exchange]
+name = "Tax_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Bank", "City"
+ "Building", "Stock Exchange", "City"
+ }
+
+[effect_stock_exchange_1]
+name = "Luxury_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Bank", "City"
+ "Building", "Stock Exchange", "City"
+ }
+
+[effect_super_highways]
+name = "Trade_Per_Tile"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Special", "Road", "City"
+ "Building", "Super Highways", "City"
+ }
+
+[effect_supermarket]
+name = "Food_Per_Tile"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Special", "Farmland", "City"
+ "Building", "Supermarket", "City"
+ }
+
+[effect_temple]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Temple", "City"
+ }
+
+[effect_temple_1]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Mysticism", "Player"
+ "Building", "Temple", "City"
+ }
+
+[effect_university]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ "Building", "University", "City"
+ }
+
+[effect_apollo_program]
+name = "Reveal_Map"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Apollo Program", "Player"
+ }
+
+[effect_apollo_program_1]
+name = "Enable_Space"
+value = 1
+reqs =
+ { "type", "name", "range", "survives"
+ "Building", "Apollo Program", "World", 1
+ }
+
+[effect_asmiths_trading_co]
+name = "Upkeep_Free"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "A.Smith's Trading Co.", "Player"
+ }
+
+[effect_colossus]
+name = "Trade_Inc_Tile"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Colossus", "City"
+ }
+
+[effect_copernicus_observatory]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Copernicus' Observatory", "City"
+ }
+
+[effect_cure_for_cancer]
+name = "Force_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Cure For Cancer", "Player"
+ }
+
+[effect_darwins_voyage]
+name = "Give_Imm_Tech"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Darwin's Voyage", "Player"
+ }
+
+[effect_great_library]
+name = "Tech_Parasite"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Library", "Player"
+ }
+
+[effect_great_wall]
+name = "Land_Defend"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
+[effect_great_wall_1]
+name = "Unit_No_Lose_Pop"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
+[effect_hanging_gardens]
+name = "Make_Happy"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Hanging Gardens", "Player"
+ }
+
+[effect_hanging_gardens_1]
+name = "Make_Happy"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Hanging Gardens", "City"
+ }
+
+[effect_hoover_dam]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_hoover_dam_1]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_hoover_dam_2]
+name = "Pollu_Prod_Pct"
+value = -50
+reqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ }
+
+[effect_isaac_newtons_college]
+name = "Science_Bonus"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "Isaac Newton's College", "City"
+ }
+
+[effect_js_bachs_cathedral]
+name = "Force_Content"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "J.S. Bach's Cathedral", "Player"
+ }
+
+[effect_king_richards_crusade]
+name = "Prod_Add_Tile"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "King Richard's Crusade", "City"
+ }
+
+[effect_leonardos_workshop]
+name = "Upgrade_Unit"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Leonardo's Workshop", "Player"
+ }
+
+[effect_lighthouse]
+name = "Sea_Move"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Lighthouse", "Player"
+ }
+
+[effect_lighthouse_1]
+name = "No_Sink_Deep"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Lighthouse", "Player"
+ }
+
+[effect_lighthouse_2]
+name = "Sea_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Lighthouse", "Player"
+ }
+
+[effect_magellans_expedition]
+name = "Sea_Move"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Magellan's Expedition", "Player"
+ }
+
+[effect_manhattan_project]
+name = "Enable_Nuke"
+value = 1
+reqs =
+ { "type", "name", "range", "survives"
+ "Building", "Manhattan Project", "World", 1
+ }
+
+[effect_marco_polos_embassy]
+name = "Have_Embassies"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Marco Polo's Embassy", "Player"
+ }
+
+[effect_michelangelos_chapel]
+name = "Make_Content"
+value = 3
+reqs =
+ { "type", "name", "range"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_michelangelos_chapel_1]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Theology", "Player"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_michelangelos_chapel_2]
+name = "Make_Content"
+value = -1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Communism", "Player"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_oracle]
+name = "Make_Content"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Temple", "City"
+ "Building", "Oracle", "Player"
+ }
+
+[effect_pyramids]
+name = "Growth_Food"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Pyramids", "Player"
+ }
+
+[effect_seti_program]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ "Building", "SETI Program", "Player"
+ }
+
+[effect_shakespeares_theatre]
+name = "No_Unhappy"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Shakespeare's Theatre", "City"
+ }
+
+[effect_statue_of_liberty]
+name = "Any_Government"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Statue of Liberty", "Player"
+ }
+
+[effect_statue_of_liberty_1]
+name = "No_Anarchy"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Statue of Liberty", "Player"
+ }
+
+[effect_sun_tzus_war_academy]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Sun Tzu's War Academy", "Player"
+ }
+
+[effect_sun_tzus_war_academy_1]
+name = "Land_Vet_Combat"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "Sun Tzu's War Academy", "Player"
+ }
+
+[effect_united_nations]
+name = "Unit_Recover"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "United Nations", "Player"
+ }
+
+[effect_womens_suffrage]
+name = "Make_Content_Mil"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Gov", "Republic", "Player"
+ "Building", "Women's Suffrage", "Player"
+ }
+
+[effect_womens_suffrage_1]
+name = "Make_Content_Mil"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Gov", "Democracy", "Player"
+ "Building", "Women's Suffrage", "Player"
+ }
+
+[effect_capitalization]
+name = "Prod_To_Gold"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Capitalization", "City"
+ }
+
Index: data/default/effects.ruleset
===================================================================
RCS file: data/default/effects.ruleset
diff -N data/default/effects.ruleset
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ data/default/effects.ruleset 31 Jan 2005 18:20:56 -0000
@@ -0,0 +1,1047 @@
+; Modifying this file:
+; You should not modify this file except to make bugfixes or
+; for other "maintenance". If you want to make custom changes,
+; you should create a new datadir subdirectory and copy this file
+; into that directory, and then modify that copy. Then use the
+; command "rulesetdir <mysubdir>" in the server to have freeciv
+; use your new customized file.
+
+; Note that the freeciv AI may not cope well with anything more
+; than minor changes.
+
+[datafile]
+description="Default effects data for Freeciv"
+options="1.0"
+
+; /* <-- avoid gettext warnings
+; */ <-- avoid gettext warnings
+
+[effect_airport]
+name = "Air_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Airport", "City"
+ }
+
+[effect_airport_1]
+name = "Air_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Airport", "City"
+ }
+
+[effect_airport_2]
+name = "Airlift"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Airport", "City"
+ }
+
+[effect_aqueduct]
+name = "Size_Adj"
+value = 4
+reqs =
+ { "type", "name", "range"
+ "Building", "Aqueduct", "City"
+ }
+
+[effect_bank]
+name = "Tax_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ "Building", "Bank", "City"
+ }
+
+[effect_bank_1]
+name = "Luxury_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ "Building", "Bank", "City"
+ }
+
+[effect_barracks]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks", "City"
+ }
+
+[effect_barracks_1]
+name = "Land_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks", "City"
+ }
+
+[effect_barracks_ii]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks II", "City"
+ }
+
+[effect_barracks_ii_1]
+name = "Land_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks II", "City"
+ }
+
+[effect_barracks_iii]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks III", "City"
+ }
+
+[effect_barracks_iii_1]
+name = "Land_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks III", "City"
+ }
+
+[effect_cathedral]
+name = "Make_Content"
+value = 3
+reqs =
+ { "type", "name", "range"
+ "Building", "Cathedral", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_cathedral_1]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Theology", "Player"
+ "Building", "Cathedral", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_cathedral_2]
+name = "Make_Content"
+value = -1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Communism", "Player"
+ "Building", "Cathedral", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_city_walls]
+name = "Land_Defend"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "City Walls", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
+[effect_city_walls_1]
+name = "Unit_No_Lose_Pop"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "City Walls", "City"
+ }
+
+[effect_coastal_defense]
+name = "Sea_Defend"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "Coastal Defense", "City"
+ }
+
+[effect_colosseum]
+name = "Make_Content"
+value = 3
+reqs =
+ { "type", "name", "range"
+ "Building", "Colosseum", "City"
+ }
+
+[effect_colosseum_1]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Electricity", "Player"
+ "Building", "Colosseum", "City"
+ }
+
+[effect_courthouse]
+name = "Corrupt_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Courthouse", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_courthouse_1]
+name = "Waste_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Courthouse", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_courthouse_2]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Gov", "Democracy", "Player"
+ "Building", "Courthouse", "City"
+ }
+
+[effect_courthouse_3]
+name = "Incite_Dist_Pct"
+value = 75
+reqs =
+ { "type", "name", "range"
+ "Building", "Courthouse", "City"
+ }
+
+[effect_factory]
+name = "Prod_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ }
+
+[effect_granary]
+name = "Growth_Food"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Granary", "City"
+ }
+
+[effect_harbour]
+name = "Food_Add_Tile"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Terrain", "Ocean", "City"
+ "Building", "Harbour", "City"
+ }
+
+[effect_hydro_plant]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Hydro Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ }
+
+[effect_hydro_plant_1]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Hydro Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ }
+
+[effect_hydro_plant_2]
+name = "Pollu_Prod_Pct"
+value = -25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Hydro Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ }
+
+[effect_hydro_plant_3]
+name = "Pollu_Prod_Pct"
+value = -25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Hydro Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ }
+
+[effect_library]
+name = "Science_Bonus"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ }
+
+[effect_marketplace]
+name = "Tax_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ }
+
+[effect_marketplace_1]
+name = "Luxury_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ }
+
+[effect_mass_transit]
+name = "Pollu_Pop_Pct"
+value = -100
+reqs =
+ { "type", "name", "range"
+ "Building", "Mass Transit", "City"
+ }
+
+[effect_mfg_plant]
+name = "Prod_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Mfg. Plant", "City"
+ }
+
+[effect_nuclear_plant]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Nuclear Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_nuclear_plant_1]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Nuclear Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_nuclear_plant_2]
+name = "Pollu_Prod_Pct"
+value = -25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Nuclear Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_nuclear_plant_3]
+name = "Pollu_Prod_Pct"
+value = -25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Nuclear Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_offshore_platform]
+name = "Prod_Add_Tile"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Terrain", "Ocean", "City"
+ "Building", "Offshore Platform", "City"
+ }
+
+[effect_palace]
+name = "Corrupt_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_1]
+name = "Waste_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_2]
+name = "Spy_Resistant"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_3]
+name = "No_Incite"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_4]
+name = "Capital_City"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_police_station]
+name = "Make_Content_Mil"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Gov", "Republic", "Player"
+ "Building", "Police Station", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Women's Suffrage", "Player"
+ }
+
+[effect_police_station_1]
+name = "Make_Content_Mil"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Gov", "Democracy", "Player"
+ "Building", "Police Station", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Women's Suffrage", "Player"
+ }
+
+[effect_port_facility]
+name = "Sea_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Port Facility", "City"
+ }
+
+[effect_port_facility_1]
+name = "Sea_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Port Facility", "City"
+ }
+
+[effect_power_plant]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Power Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ "Building", "Hydro Plant", "City"
+ }
+
+[effect_power_plant_1]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Power Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ "Building", "Hydro Plant", "City"
+ }
+
+[effect_recycling_center]
+name = "Pollu_Prod_Pct"
+value = -66
+reqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ }
+
+[effect_research_lab]
+name = "Science_Bonus"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ "Building", "Research Lab", "City"
+ }
+
+[effect_research_lab_1]
+name = "Science_Bonus"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "University", "City"
+ "Building", "Research Lab", "City"
+ }
+
+[effect_sam_battery]
+name = "Air_Defend"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "SAM Battery", "City"
+ }
+
+[effect_sdi_defense]
+name = "Nuke_Proof"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "SDI Defense", "City"
+ }
+
+[effect_sdi_defense_1]
+name = "Missile_Defend"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "SDI Defense", "City"
+ }
+
+[effect_sewer_system]
+name = "Size_Unlimit"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Aqueduct", "City"
+ "Building", "Sewer System", "City"
+ }
+
+[effect_space_component]
+name = "SS_Component"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Space Component", "City"
+ }
+
+[effect_space_module]
+name = "SS_Module"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Space Module", "City"
+ }
+
+[effect_space_structural]
+name = "SS_Structural"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Space Structural", "City"
+ }
+
+[effect_stock_exchange]
+name = "Tax_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Bank", "City"
+ "Building", "Stock Exchange", "City"
+ }
+
+[effect_stock_exchange_1]
+name = "Luxury_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Bank", "City"
+ "Building", "Stock Exchange", "City"
+ }
+
+[effect_super_highways]
+name = "Trade_Per_Tile"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Special", "Road", "City"
+ "Building", "Super Highways", "City"
+ }
+
+[effect_supermarket]
+name = "Food_Per_Tile"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Special", "Farmland", "City"
+ "Building", "Supermarket", "City"
+ }
+
+[effect_temple]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Temple", "City"
+ }
+
+[effect_temple_1]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Mysticism", "Player"
+ "Building", "Temple", "City"
+ }
+
+[effect_university]
+name = "Science_Bonus"
+value = 150
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ "Building", "University", "City"
+ }
+
+[effect_apollo_program]
+name = "Reveal_Map"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Apollo Program", "Player"
+ }
+
+[effect_apollo_program_1]
+name = "Enable_Space"
+value = 1
+reqs =
+ { "type", "name", "range", "survives"
+ "Building", "Apollo Program", "World", 1
+ }
+
+[effect_asmiths_trading_co]
+name = "Upkeep_Free"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "A.Smith's Trading Co.", "Player"
+ }
+
+[effect_colossus]
+name = "Trade_Inc_Tile"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Colossus", "City"
+ }
+
+[effect_copernicus_observatory]
+name = "Science_Bonus"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "Copernicus' Observatory", "City"
+ }
+
+[effect_cure_for_cancer]
+name = "Force_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Cure For Cancer", "Player"
+ }
+
+[effect_darwins_voyage]
+name = "Give_Imm_Tech"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Darwin's Voyage", "Player"
+ }
+
+[effect_eiffel_tower]
+name = "Regen_Reputation"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Eiffel Tower", "Player"
+ }
+
+[effect_eiffel_tower_1]
+name = "Gain_AI_Love"
+value = 20
+reqs =
+ { "type", "name", "range"
+ "Building", "Eiffel Tower", "Player"
+ }
+
+[effect_great_library]
+name = "Tech_Parasite"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Library", "Player"
+ }
+
+[effect_great_wall]
+name = "Land_Defend"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
+[effect_great_wall_1]
+name = "Unit_No_Lose_Pop"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
+[effect_hanging_gardens]
+name = "Make_Happy"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Hanging Gardens", "Player"
+ }
+
+[effect_hanging_gardens_1]
+name = "Make_Happy"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Hanging Gardens", "City"
+ }
+
+[effect_hoover_dam]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_hoover_dam_1]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_hoover_dam_2]
+name = "Pollu_Prod_Pct"
+value = -25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Hoover Dam", "Player"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ }
+
+[effect_hoover_dam_3]
+name = "Pollu_Prod_Pct"
+value = -25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Hoover Dam", "Player"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ }
+
+[effect_isaac_newtons_college]
+name = "Science_Bonus"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "University", "City"
+ "Building", "Isaac Newton's College", "Player"
+ }
+
+[effect_js_bachs_cathedral]
+name = "Force_Content"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "J.S. Bach's Cathedral", "Player"
+ }
+
+[effect_king_richards_crusade]
+name = "Prod_Add_Tile"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "King Richard's Crusade", "City"
+ }
+
+[effect_leonardos_workshop]
+name = "Upgrade_Unit"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Leonardo's Workshop", "Player"
+ }
+
+[effect_lighthouse]
+name = "Sea_Move"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Lighthouse", "Player"
+ }
+
+[effect_lighthouse_1]
+name = "No_Sink_Deep"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Lighthouse", "Player"
+ }
+
+[effect_lighthouse_2]
+name = "Sea_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Lighthouse", "Player"
+ }
+
+[effect_magellans_expedition]
+name = "Sea_Move"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Magellan's Expedition", "Player"
+ }
+
+[effect_manhattan_project]
+name = "Enable_Nuke"
+value = 1
+reqs =
+ { "type", "name", "range", "survives"
+ "Building", "Manhattan Project", "World", 1
+ }
+
+[effect_marco_polos_embassy]
+name = "Have_Embassies"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Marco Polo's Embassy", "Player"
+ }
+
+[effect_michelangelos_chapel]
+name = "Make_Content"
+value = 3
+reqs =
+ { "type", "name", "range"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_michelangelos_chapel_1]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Theology", "Player"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_michelangelos_chapel_2]
+name = "Make_Content"
+value = -1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Communism", "Player"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_oracle]
+name = "Make_Content"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Temple", "City"
+ "Building", "Oracle", "Player"
+ }
+
+[effect_pyramids]
+name = "Growth_Food"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Pyramids", "Player"
+ }
+
+[effect_seti_program]
+name = "Science_Bonus"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "Research Lab", "City"
+ "Building", "SETI Program", "Player"
+ }
+
+[effect_shakespeares_theatre]
+name = "No_Unhappy"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Shakespeare's Theatre", "City"
+ }
+
+[effect_statue_of_liberty]
+name = "Any_Government"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Statue of Liberty", "Player"
+ }
+
+[effect_statue_of_liberty_1]
+name = "No_Anarchy"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Statue of Liberty", "Player"
+ }
+
+[effect_sun_tzus_war_academy]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Sun Tzu's War Academy", "Player"
+ }
+
+[effect_sun_tzus_war_academy_1]
+name = "Land_Vet_Combat"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Sun Tzu's War Academy", "Player"
+ }
+
+[effect_united_nations]
+name = "Unit_Recover"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "United Nations", "Player"
+ }
+
+[effect_womens_suffrage]
+name = "Make_Content_Mil"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Gov", "Republic", "Player"
+ "Building", "Women's Suffrage", "Player"
+ }
+
+[effect_womens_suffrage_1]
+name = "Make_Content_Mil"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Gov", "Democracy", "Player"
+ "Building", "Women's Suffrage", "Player"
+ }
+
+[effect_coinage]
+name = "Prod_To_Gold"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Coinage", "City"
+ }
+
Index: data/history/effects.ruleset
===================================================================
RCS file: data/history/effects.ruleset
diff -N data/history/effects.ruleset
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ data/history/effects.ruleset 31 Jan 2005 18:20:56 -0000
@@ -0,0 +1,980 @@
+; Modifying this file:
+; You should not modify this file except to make bugfixes or
+; for other "maintenance". If you want to make custom changes,
+; you should create a new datadir subdirectory and copy this file
+; into that directory, and then modify that copy. Then use the
+; command "rulesetdir <mysubdir>" in the server to have freeciv
+; use your new customized file.
+
+; Note that the freeciv AI may not cope well with anything more
+; than minor changes.
+
+[datafile]
+description="History effects data for Freeciv"
+options="1.0"
+
+; /* <-- avoid gettext warnings
+; */ <-- avoid gettext warnings
+
+[effect_airport]
+name = "Air_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Airport", "City"
+ }
+
+[effect_airport_1]
+name = "Air_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Airport", "City"
+ }
+
+[effect_airport_2]
+name = "Airlift"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Airport", "City"
+ }
+
+[effect_aqueduct]
+name = "Size_Adj"
+value = 4
+reqs =
+ { "type", "name", "range"
+ "Building", "Aqueduct", "City"
+ }
+
+[effect_bank]
+name = "Tax_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ "Building", "Bank", "City"
+ }
+
+[effect_bank_1]
+name = "Luxury_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ "Building", "Bank", "City"
+ }
+
+[effect_barracks]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks", "City"
+ }
+
+[effect_barracks_1]
+name = "Land_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks", "City"
+ }
+
+[effect_barracks_ii]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks II", "City"
+ }
+
+[effect_barracks_ii_1]
+name = "Land_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks II", "City"
+ }
+
+[effect_barracks_iii]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks III", "City"
+ }
+
+[effect_barracks_iii_1]
+name = "Land_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Barracks III", "City"
+ }
+
+[effect_cathedral]
+name = "Make_Content"
+value = 3
+reqs =
+ { "type", "name", "range"
+ "Building", "Cathedral", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_cathedral_1]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Theology", "Player"
+ "Building", "Cathedral", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_cathedral_2]
+name = "Make_Content"
+value = -1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Communism", "Player"
+ "Building", "Cathedral", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_city_walls]
+name = "Land_Defend"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "City Walls", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
+[effect_city_walls_1]
+name = "Unit_No_Lose_Pop"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "City Walls", "City"
+ }
+
+[effect_coastal_defense]
+name = "Sea_Defend"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "Coastal Defense", "City"
+ }
+
+[effect_colosseum]
+name = "Make_Content"
+value = 3
+reqs =
+ { "type", "name", "range"
+ "Building", "Colosseum", "City"
+ }
+
+[effect_colosseum_1]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Electricity", "Player"
+ "Building", "Colosseum", "City"
+ }
+
+[effect_courthouse]
+name = "Corrupt_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Courthouse", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_courthouse_1]
+name = "Waste_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Courthouse", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_courthouse_2]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Gov", "Democracy", "Player"
+ "Building", "Courthouse", "City"
+ }
+
+[effect_courthouse_3]
+name = "Incite_Dist_Pct"
+value = 75
+reqs =
+ { "type", "name", "range"
+ "Building", "Courthouse", "City"
+ }
+
+[effect_factory]
+name = "Prod_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ }
+
+[effect_granary]
+name = "Growth_Food"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Granary", "City"
+ }
+
+[effect_harbour]
+name = "Food_Add_Tile"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Terrain", "Ocean", "City"
+ "Building", "Harbour", "City"
+ }
+
+[effect_hydro_plant]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Hydro Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ }
+
+[effect_hydro_plant_1]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Hydro Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ }
+
+[effect_hydro_plant_2]
+name = "Pollu_Prod_Pct"
+value = -50
+reqs =
+ { "type", "name", "range"
+ "Building", "Hydro Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ }
+
+[effect_library]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ }
+
+[effect_marketplace]
+name = "Tax_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ }
+
+[effect_marketplace_1]
+name = "Luxury_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Marketplace", "City"
+ }
+
+[effect_mass_transit]
+name = "Pollu_Pop_Pct"
+value = -100
+reqs =
+ { "type", "name", "range"
+ "Building", "Mass Transit", "City"
+ }
+
+[effect_mfg_plant]
+name = "Prod_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Mfg. Plant", "City"
+ }
+
+[effect_nuclear_plant]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Nuclear Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_nuclear_plant_1]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Nuclear Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_nuclear_plant_2]
+name = "Pollu_Prod_Pct"
+value = -50
+reqs =
+ { "type", "name", "range"
+ "Building", "Nuclear Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_offshore_platform]
+name = "Prod_Add_Tile"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Terrain", "Ocean", "City"
+ "Building", "Offshore Platform", "City"
+ }
+
+[effect_palace]
+name = "Corrupt_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_1]
+name = "Waste_Pct"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_2]
+name = "Spy_Resistant"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_3]
+name = "No_Incite"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_palace_4]
+name = "Capital_City"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Palace", "City"
+ }
+
+[effect_police_station]
+name = "Make_Content_Mil"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Gov", "Republic", "Player"
+ "Building", "Police Station", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Women's Suffrage", "Player"
+ }
+
+[effect_police_station_1]
+name = "Make_Content_Mil"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Gov", "Democracy", "Player"
+ "Building", "Police Station", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Women's Suffrage", "Player"
+ }
+
+[effect_port_facility]
+name = "Sea_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Port Facility", "City"
+ }
+
+[effect_port_facility_1]
+name = "Sea_Regen"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Port Facility", "City"
+ }
+
+[effect_power_plant]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Power Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ "Building", "Hydro Plant", "City"
+ }
+
+[effect_power_plant_1]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Power Plant", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ "Building", "Nuclear Plant", "City"
+ "Building", "Hydro Plant", "City"
+ }
+
+[effect_recycling_center]
+name = "Pollu_Prod_Pct"
+value = -66
+reqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ }
+
+[effect_research_lab]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ "Building", "Research Lab", "City"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "SETI Program", "Player"
+ }
+
+[effect_sam_battery]
+name = "Air_Defend"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "SAM Battery", "City"
+ }
+
+[effect_sdi_defense]
+name = "Nuke_Proof"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "SDI Defense", "City"
+ }
+
+[effect_sdi_defense_1]
+name = "Missile_Defend"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "SDI Defense", "City"
+ }
+
+[effect_sewer_system]
+name = "Size_Unlimit"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Aqueduct", "City"
+ "Building", "Sewer System", "City"
+ }
+
+[effect_space_component]
+name = "SS_Component"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Space Component", "City"
+ }
+
+[effect_space_module]
+name = "SS_Module"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Space Module", "City"
+ }
+
+[effect_space_structural]
+name = "SS_Structural"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Space Structural", "City"
+ }
+
+[effect_stock_exchange]
+name = "Tax_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Bank", "City"
+ "Building", "Stock Exchange", "City"
+ }
+
+[effect_stock_exchange_1]
+name = "Luxury_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Bank", "City"
+ "Building", "Stock Exchange", "City"
+ }
+
+[effect_super_highways]
+name = "Trade_Per_Tile"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Special", "Road", "City"
+ "Building", "Super Highways", "City"
+ }
+
+[effect_supermarket]
+name = "Food_Per_Tile"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Special", "Farmland", "City"
+ "Building", "Supermarket", "City"
+ }
+
+[effect_temple]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Temple", "City"
+ }
+
+[effect_temple_1]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Mysticism", "Player"
+ "Building", "Temple", "City"
+ }
+
+[effect_university]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ "Building", "University", "City"
+ }
+
+[effect_apollo_program]
+name = "Reveal_Map"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Apollo Program", "Player"
+ }
+
+[effect_apollo_program_1]
+name = "Enable_Space"
+value = 1
+reqs =
+ { "type", "name", "range", "survives"
+ "Building", "Apollo Program", "World", 1
+ }
+
+[effect_asmiths_trading_co]
+name = "Upkeep_Free"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "A.Smith's Trading Co.", "Player"
+ }
+
+[effect_colossus]
+name = "Trade_Inc_Tile"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Colossus", "City"
+ }
+
+[effect_copernicus_observatory]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Copernicus' Observatory", "City"
+ }
+
+[effect_cure_for_cancer]
+name = "Force_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Cure For Cancer", "Player"
+ }
+
+[effect_darwins_voyage]
+name = "Give_Imm_Tech"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Darwin's Voyage", "Player"
+ }
+
+[effect_great_library]
+name = "Tech_Parasite"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Library", "Player"
+ }
+
+[effect_great_wall]
+name = "Land_Defend"
+value = 200
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
+[effect_great_wall_1]
+name = "Unit_No_Lose_Pop"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Great Wall", "Player"
+ }
+
+[effect_hanging_gardens]
+name = "Make_Happy"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Hanging Gardens", "Player"
+ }
+
+[effect_hanging_gardens_1]
+name = "Make_Happy"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Hanging Gardens", "City"
+ }
+
+[effect_hoover_dam]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Factory", "City"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_hoover_dam_1]
+name = "Prod_Bonus"
+value = 25
+reqs =
+ { "type", "name", "range"
+ "Building", "Mfg. Plant", "City"
+ "Building", "Hoover Dam", "Player"
+ }
+
+[effect_hoover_dam_2]
+name = "Pollu_Prod_Pct"
+value = -50
+reqs =
+ { "type", "name", "range"
+ "Building", "Hoover Dam", "Player"
+ }
+nreqs =
+ { "type", "name", "range"
+ "Building", "Recycling Center", "City"
+ }
+
+[effect_isaac_newtons_college]
+name = "Science_Bonus"
+value = 100
+reqs =
+ { "type", "name", "range"
+ "Building", "Isaac Newton's College", "City"
+ }
+
+[effect_js_bachs_cathedral]
+name = "Force_Content"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "J.S. Bach's Cathedral", "Player"
+ }
+
+[effect_king_richards_crusade]
+name = "Prod_Add_Tile"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "King Richard's Crusade", "City"
+ }
+
+[effect_leonardos_workshop]
+name = "Upgrade_Unit"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Leonardo's Workshop", "Player"
+ }
+
+[effect_lighthouse]
+name = "Sea_Move"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Lighthouse", "Player"
+ }
+
+[effect_lighthouse_1]
+name = "No_Sink_Deep"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Lighthouse", "Player"
+ }
+
+[effect_lighthouse_2]
+name = "Sea_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Lighthouse", "Player"
+ }
+
+[effect_magellans_expedition]
+name = "Sea_Move"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Magellan's Expedition", "Player"
+ }
+
+[effect_manhattan_project]
+name = "Enable_Nuke"
+value = 1
+reqs =
+ { "type", "name", "range", "survives"
+ "Building", "Manhattan Project", "World", 1
+ }
+
+[effect_marco_polos_embassy]
+name = "Have_Embassies"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Marco Polo's Embassy", "Player"
+ }
+
+[effect_michelangelos_chapel]
+name = "Make_Content"
+value = 3
+reqs =
+ { "type", "name", "range"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_michelangelos_chapel_1]
+name = "Make_Content"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Theology", "Player"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_michelangelos_chapel_2]
+name = "Make_Content"
+value = -1
+reqs =
+ { "type", "name", "range"
+ "Tech", "Communism", "Player"
+ "Building", "Michelangelo's Chapel", "Player"
+ }
+
+[effect_oracle]
+name = "Make_Content"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "Temple", "City"
+ "Building", "Oracle", "Player"
+ }
+
+[effect_pyramids]
+name = "Growth_Food"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Pyramids", "Player"
+ }
+
+[effect_seti_program]
+name = "Science_Bonus"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Library", "City"
+ "Building", "SETI Program", "Player"
+ }
+
+[effect_shakespeares_theatre]
+name = "No_Unhappy"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Shakespeare's Theatre", "City"
+ }
+
+[effect_statue_of_liberty]
+name = "Any_Government"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Statue of Liberty", "Player"
+ }
+
+[effect_statue_of_liberty_1]
+name = "No_Anarchy"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Statue of Liberty", "Player"
+ }
+
+[effect_sun_tzus_war_academy]
+name = "Land_Veteran"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Sun Tzu's War Academy", "Player"
+ }
+
+[effect_sun_tzus_war_academy_1]
+name = "Land_Vet_Combat"
+value = 50
+reqs =
+ { "type", "name", "range"
+ "Building", "Sun Tzu's War Academy", "Player"
+ }
+
+[effect_united_nations]
+name = "Unit_Recover"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Building", "United Nations", "Player"
+ }
+
+[effect_womens_suffrage]
+name = "Make_Content_Mil"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Gov", "Republic", "Player"
+ "Building", "Women's Suffrage", "Player"
+ }
+
+[effect_womens_suffrage_1]
+name = "Make_Content_Mil"
+value = 2
+reqs =
+ { "type", "name", "range"
+ "Gov", "Democracy", "Player"
+ "Building", "Women's Suffrage", "Player"
+ }
+
+[effect_coinage]
+name = "Prod_To_Gold"
+value = 1
+reqs =
+ { "type", "name", "range"
+ "Building", "Coinage", "City"
+ }
+
Index: server/plrhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.c,v
retrieving revision 1.355
diff -u -r1.355 plrhand.c
--- server/plrhand.c 22 Jan 2005 21:12:10 -0000 1.355
+++ server/plrhand.c 31 Jan 2005 18:20:57 -0000
@@ -130,21 +130,21 @@
void do_tech_parasite_effect(struct player *pplayer)
{
int mod;
- struct effect_source_vector sources;
+ struct effect_list *plist = effect_list_new();
/* Note that two EFT_TECH_PARASITE effects will combine into a single,
* much worse effect. */
- if ((mod = get_player_bonus_sources(&sources, pplayer,
+ if ((mod = get_player_bonus_effects(plist, pplayer,
EFT_TECH_PARASITE)) > 0) {
char buf[512];
buf[0] = '\0';
- effect_source_vector_iterate(&sources, src) {
+ effect_list_iterate(plist, peffect) {
if (buf[0] != '\0') {
sz_strlcat(buf, ", ");
}
- sz_strlcat(buf, get_improvement_name(src->building));
- } effect_source_vector_iterate_end;
+ get_effect_req_text(peffect, buf, sizeof(buf));
+ } effect_list_iterate_end;
tech_type_iterate(i) {
if (get_invention(pplayer, i) != TECH_KNOWN
@@ -165,7 +165,8 @@
}
} tech_type_iterate_end;
}
- effect_source_vector_free(&sources);
+ effect_list_unlink_all(plist);
+ effect_list_free(plist);
}
/****************************************************************************
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.229
diff -u -r1.229 ruleset.c
--- server/ruleset.c 29 Jan 2005 17:58:19 -0000 1.229
+++ server/ruleset.c 31 Jan 2005 18:20:57 -0000
@@ -90,6 +90,7 @@
static void load_ruleset_terrain(struct section_file *file);
static void load_ruleset_cities(struct section_file *file);
static void load_ruleset_nations(struct section_file *file);
+static void load_ruleset_effects(struct section_file *file);
static void load_ruleset_game(void);
@@ -1157,57 +1158,6 @@
(void) check_ruleset_capabilities(file, "+1.10.1", filename);
- /* Parse effect source equivalency groups. */
- sec = secfile_get_secnames_prefix(file, "group_", &nval);
- for (i = 0; i < nval; i++) {
- struct effect_group *group;
- char name[MAX_LEN_NAME];
-
- item = secfile_lookup_str(file, "%s.name", sec[i]);
- sz_strlcpy(name, item);
-
- group = effect_group_new(name);
-
- for (j = 0;
- (item = secfile_lookup_str_default(file, NULL,
- "%s.elements%d.building",
- sec[i], j));
- j++) {
- Impr_Type_id id;
- enum req_range range;
- bool survives;
-
- if ((id = find_improvement_by_name(item)) == B_LAST) {
- freelog(LOG_ERROR,
- /* TRANS: Obscure ruleset error */
- _("Group %s lists unknown building: \"%s\" (%s)"),
- name, item, filename);
- continue;
- }
-
- item = secfile_lookup_str_default(file, NULL, "%s.elements%d.range",
- sec[i], j);
- if (item) {
- if ((range = req_range_from_str(item)) == REQ_RANGE_LAST) {
- freelog(LOG_ERROR,
- /* TRANS: Obscure ruleset error */
- _("Group %s lists bad range: \"%s\" (%s)"),
- name, item, filename);
- continue;
- }
- } else {
- range = REQ_RANGE_CITY;
- }
-
- survives
- = secfile_lookup_bool_default(file, FALSE, "%s.elements%d.survives",
- sec[i], j);
-
- effect_group_add_element(group, id, range, survives);
- }
- }
- free(sec);
-
sec = secfile_get_secnames_prefix(file, "building_", &nval);
for (i = 0; i < nval; i++) {
@@ -1279,83 +1229,6 @@
b->sabotage = secfile_lookup_int(file, "%s.sabotage", sec[i]);
- /* Parse building effects and add them to the effects ruleset cache. */
- {
- for (j = 0;
- (item = secfile_lookup_str_default(file, NULL, "%s.effect%d.name",
- sec[i], j));
- j++) {
- int value;
- enum effect_type eff;
- enum req_range range;
- bool survives;
- struct requirement req;
- char *req_type, *req_value;
- int equiv;
-
- if ((eff = effect_type_from_str(item)) == EFT_LAST) {
- freelog(LOG_ERROR,
- /* TRANS: Obscure ruleset error */
- _("Building %s lists unknown effect type: \"%s\" (%s)"),
- b->name, item, filename);
- continue;
- }
-
- item = secfile_lookup_str_default(file, NULL, "%s.effect%d.range",
- sec[i], j);
- if (item) {
- if ((range = req_range_from_str(item)) == REQ_RANGE_LAST) {
- freelog(LOG_ERROR,
- /* TRANS: Obscure ruleset error */
- _("Building %s lists bad range: \"%s\" (%s)"),
- b->name, item, filename);
- continue;
- }
- } else {
- range = REQ_RANGE_CITY;
- }
-
- survives = secfile_lookup_bool_default(file, FALSE,
"%s.effect%d.survives",
- sec[i], j);
-
- value = secfile_lookup_int_default(file, 1, "%s.effect%d.value",
- sec[i], j);
-
- /* Sometimes the ruleset will have to list "" here. */
- item = secfile_lookup_str_default(file, "", "%s.effect%d.equiv",
- sec[i], j);
- if (item[0] != '\0') {
- if ((equiv = find_effect_group_id(item)) == -1) {
- freelog(LOG_ERROR,
- /* TRANS: Obscure ruleset error */
- _("Building %s lists bad effect group: \"%s\" (%s)"),
- b->name, item, filename);
- continue;
- }
- } else {
- equiv = -1;
- }
-
- /* Sometimes the ruleset will have to list "" here. */
- req_type = secfile_lookup_str_default(file, NULL,
- "%s.effect%d.req_type",
- sec[i], j);
- req_value = secfile_lookup_str_default(file, "", "%s.effect%d.req",
- sec[i], j);
- req = req_from_str(req_type, "", FALSE, req_value);
- if (req.type == REQ_LAST) {
- /* Error. Log it, clear the req and continue. */
- freelog(LOG_ERROR,
- /* TRANS: Obscure ruleset error */
- _("Building %s has unknown req: \"%s\" \"%s\" (%s)"),
- b->name, req_type, req_value, filename);
- req.type = REQ_NONE;
- }
-
- ruleset_cache_add(i, eff, range, survives, value, &req, equiv);
- }
- }
-
sz_strlcpy(b->graphic_str,
secfile_lookup_str_default(file, "-", "%s.graphic", sec[i]));
sz_strlcpy(b->graphic_alt,
@@ -1369,26 +1242,6 @@
b->helptext = lookup_helptext(file, sec[i]);
}
- /*
- * Hack to allow code that explicitly checks for Palace or City Walls
- * to work.
- */
- game.palace_building = get_building_for_effect(EFT_CAPITAL_CITY);
- if (game.palace_building == B_LAST) {
- freelog(LOG_FATAL,
- /* TRANS: Obscure ruleset error */
- _("Cannot find any palace building"));
- exit(EXIT_FAILURE);
- }
-
- game.land_defend_building = get_building_for_effect(EFT_LAND_DEFEND);
- if (game.land_defend_building == B_LAST) {
- freelog(LOG_FATAL,
- /* TRANS: Obscure ruleset error */
- _("Cannot find any land defend building"));
- exit(EXIT_FAILURE);
- }
-
/* Some more consistency checking: */
impr_type_iterate(i) {
b = &improvement_types[i];
@@ -2409,11 +2262,11 @@
name, j);
struct requirement req = req_from_str(type, range, survives, value);
- if (req.type == REQ_LAST) {
+ if (req.source.type == REQ_LAST) {
freelog(LOG_ERROR,
"Specialist %s has unknown req: \"%s\" \"%s\" \"%s\" %d (%s)",
name, type, range, value, survives, filename);
- req.type = REQ_NONE;
+ req.source.type = REQ_NONE;
}
game.rgame.specialists[i].req[j] = req;
@@ -2490,9 +2343,118 @@
}
/**************************************************************************
+Load effects requirement list.
+**************************************************************************/
+static void load_req_list(struct section_file *file,
+ const char *sec, const char *sub,
+ bool neg, struct effect *peffect)
+{
+ char *type, *name;
+ int j;
+ const char *filename;
+
+ filename = secfile_filename(file);
+
+ for (j = 0;
+ (type = secfile_lookup_str_default(file, NULL, "%s.%s%d.type",
+ sec, sub, j));
+ j++) {
+ char *range;
+ bool survives;
+ struct requirement req;
+
+ name = secfile_lookup_str(file, "%s.%s%d.name", sec, sub, j);
+ range = secfile_lookup_str(file, "%s.%s%d.range", sec, sub, j);
+
+ survives = secfile_lookup_bool_default(file, FALSE,
+ "%s.%s%d.survives", sec, sub, j);
+
+ req = req_from_str(type, range, survives, name);
+ if (req.source.type == REQ_LAST) {
+ /* Error. Log it, clear the req and continue. */
+ freelog(LOG_ERROR,
+ /* TRANS: Obscure ruleset error */
+ _("Section %s has unknown req: \"%s\" \"%s\" (%s)"),
+ sec, type, name, filename);
+ req.source.type = REQ_NONE;
+ } else {
+ struct requirement *preq;
+
+ preq = fc_malloc(sizeof(*preq));
+ *preq = req;
+
+ effect_req_append(peffect, neg, preq);
+ }
+ }
+}
+
+/**************************************************************************
+Load effects.ruleset file
+**************************************************************************/
+static void load_ruleset_effects(struct section_file *file)
+{
+ char **sec, *type;
+ int i, nval;
+ const char *filename;
+
+ filename = secfile_filename(file);
+ (void) check_ruleset_capabilities(file, "+1.0", filename);
+ (void) section_file_lookup(file, "datafile.description"); /* unused */
+
+ /* Parse effects and add them to the effects ruleset cache. */
+ sec = secfile_get_secnames_prefix(file, "effect_", &nval);
+ for (i = 0; i < nval; i++) {
+ enum effect_type eff;
+ int value;
+ struct effect *peffect;
+
+ type = secfile_lookup_str(file, "%s.name", sec[i]);
+
+ if ((eff = effect_type_from_str(type)) == EFT_LAST) {
+ freelog(LOG_ERROR,
+ /* TRANS: Obscure ruleset error */
+ _("Section %s lists unknown effect type: \"%s\" (%s)"),
+ sec[i], type, filename);
+ continue;
+ }
+
+ value = secfile_lookup_int_default(file, 1, "%s.value", sec[i]);
+
+ peffect = effect_new(eff, value);
+
+ load_req_list(file, sec[i], "reqs", FALSE, peffect);
+ load_req_list(file, sec[i], "nreqs", TRUE, peffect);
+ }
+ free(sec);
+
+ section_file_check_unused(file, filename);
+ section_file_free(file);
+
+ /*
+ * Hack to allow code that explicitly checks for Palace or City Walls
+ * to work.
+ */
+ game.palace_building = get_building_for_effect(EFT_CAPITAL_CITY);
+ if (game.palace_building == B_LAST) {
+ freelog(LOG_FATAL,
+ /* TRANS: Obscure ruleset error */
+ _("Cannot find any palace building"));
+ exit(EXIT_FAILURE);
+ }
+
+ game.land_defend_building = get_building_for_effect(EFT_LAND_DEFEND);
+ if (game.land_defend_building == B_LAST) {
+ freelog(LOG_FATAL,
+ /* TRANS: Obscure ruleset error */
+ _("Cannot find any land defend building"));
+ exit(EXIT_FAILURE);
+ }
+}
+
+/**************************************************************************
Load ruleset file
**************************************************************************/
-static void load_ruleset_game()
+static void load_ruleset_game(void)
{
struct section_file file;
char *sval;
@@ -3061,7 +3023,7 @@
void load_rulesets(void)
{
struct section_file techfile, unitfile, buildfile, govfile, terrfile;
- struct section_file cityfile, nationfile;
+ struct section_file cityfile, nationfile, effectfile;
freelog(LOG_NORMAL, _("Loading rulesets"));
@@ -3086,6 +3048,8 @@
openload_ruleset_file(&nationfile, "nations");
load_nation_names(&nationfile);
+ openload_ruleset_file(&effectfile, "effects");
+
load_ruleset_techs(&techfile);
load_ruleset_cities(&cityfile);
load_ruleset_governments(&govfile);
@@ -3093,6 +3057,7 @@
load_ruleset_terrain(&terrfile); /* terrain must precede nations */
load_ruleset_buildings(&buildfile);
load_ruleset_nations(&nationfile);
+ load_ruleset_effects(&effectfile);
load_ruleset_game();
translate_data_names();
}
- [Freeciv-Dev] (PR#12019) Effects TNG, Vasco Alexandre da Silva Costa, 2005/01/26
- [Freeciv-Dev] (PR#12019) Effects TNG, Vasco Alexandre da Silva Costa, 2005/01/26
- [Freeciv-Dev] (PR#12019) Effects TNG, Vasco Alexandre da Silva Costa, 2005/01/27
- [Freeciv-Dev] (PR#12019) Effects TNG, Vasco Alexandre da Silva Costa, 2005/01/28
- [Freeciv-Dev] (PR#12019) Effects TNG, Vasco Alexandre da Silva Costa, 2005/01/28
- [Freeciv-Dev] (PR#12019) Effects TNG, Jason Short, 2005/01/30
- [Freeciv-Dev] (PR#12019) Effects TNG, Vasco Alexandre da Silva Costa, 2005/01/31
- [Freeciv-Dev] (PR#12019) Effects TNG,
Jason Short <=
|
|