Rework building requirement checking to use tri-state logic.
[freeciv.git] / common / requirements.c
blob3fa8405434a88ec5e832170ef0e5e0b034259ce7
1 /**********************************************************************
2 Freeciv - Copyright (C) 1996-2004 - The Freeciv Project
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
13 #ifdef HAVE_CONFIG_H
14 #include <fc_config.h>
15 #endif
17 /* utility */
18 #include "fcintl.h"
19 #include "game.h"
20 #include "log.h"
21 #include "support.h"
23 /* common */
24 #include "citizens.h"
25 #include "government.h"
26 #include "improvement.h"
27 #include "map.h"
28 #include "road.h"
29 #include "specialist.h"
31 #include "requirements.h"
33 /**************************************************************************
34 Parse requirement type (kind) and value strings into a universal
35 structure. Passing in a NULL type is considered VUT_NONE (not an error).
37 Pass this some values like "Building", "Factory".
38 FIXME: ensure that every caller checks error return!
39 **************************************************************************/
40 struct universal universal_by_rule_name(const char *kind,
41 const char *value)
43 struct universal source;
45 source.kind = universals_n_by_name(kind, fc_strcasecmp);
46 if (!universals_n_is_valid(source.kind)) {
47 return source;
50 /* Finally scan the value string based on the type of the source. */
51 switch (source.kind) {
52 case VUT_NONE:
53 return source;
54 case VUT_ADVANCE:
55 source.value.advance = advance_by_rule_name(value);
56 if (source.value.advance != NULL) {
57 return source;
59 break;
60 case VUT_TECHFLAG:
61 source.value.techflag
62 = tech_flag_id_by_name(value, fc_strcasecmp);
63 if (tech_flag_id_is_valid(source.value.techflag)) {
64 return source;
66 break;
67 case VUT_GOVERNMENT:
68 source.value.govern = government_by_rule_name(value);
69 if (source.value.govern != NULL) {
70 return source;
72 break;
73 case VUT_IMPROVEMENT:
74 source.value.building = improvement_by_rule_name(value);
75 if (source.value.building != NULL) {
76 return source;
78 break;
79 case VUT_SPECIAL:
80 source.value.special = special_by_rule_name(value);
81 if (source.value.special != S_LAST) {
82 return source;
84 break;
85 case VUT_TERRAIN:
86 source.value.terrain = terrain_by_rule_name(value);
87 if (source.value.terrain != T_UNKNOWN) {
88 return source;
90 break;
91 case VUT_TERRFLAG:
92 source.value.terrainflag
93 = terrain_flag_id_by_name(value, fc_strcasecmp);
94 if (terrain_flag_id_is_valid(source.value.terrainflag)) {
95 return source;
97 break;
98 case VUT_RESOURCE:
99 source.value.resource = resource_by_rule_name(value);
100 if (source.value.resource != NULL) {
101 return source;
103 break;
104 case VUT_NATION:
105 source.value.nation = nation_by_rule_name(value);
106 if (source.value.nation != NO_NATION_SELECTED) {
107 return source;
109 break;
110 case VUT_NATIONALITY:
111 source.value.nationality = nation_by_rule_name(value);
112 if (source.value.nationality != NO_NATION_SELECTED) {
113 return source;
115 break;
116 case VUT_UTYPE:
117 source.value.utype = unit_type_by_rule_name(value);
118 if (source.value.utype) {
119 return source;
121 break;
122 case VUT_UTFLAG:
123 source.value.unitflag = unit_type_flag_id_by_name(value, fc_strcasecmp);
124 if (unit_type_flag_id_is_valid(source.value.unitflag)) {
125 return source;
127 break;
128 case VUT_UCLASS:
129 source.value.uclass = unit_class_by_rule_name(value);
130 if (source.value.uclass) {
131 return source;
133 break;
134 case VUT_UCFLAG:
135 source.value.unitclassflag
136 = unit_class_flag_id_by_name(value, fc_strcasecmp);
137 if (unit_class_flag_id_is_valid(source.value.unitclassflag)) {
138 return source;
140 break;
141 case VUT_OTYPE:
142 source.value.outputtype = output_type_by_identifier(value);
143 if (source.value.outputtype != O_LAST) {
144 return source;
146 break;
147 case VUT_SPECIALIST:
148 source.value.specialist = specialist_by_rule_name(value);
149 if (source.value.specialist) {
150 return source;
152 case VUT_MINSIZE:
153 source.value.minsize = atoi(value);
154 if (source.value.minsize > 0) {
155 return source;
157 break;
158 case VUT_AI_LEVEL:
159 source.value.ai_level = ai_level_by_name(value);
160 if (source.value.ai_level != AI_LEVEL_LAST) {
161 return source;
163 break;
164 case VUT_TERRAINCLASS:
165 source.value.terrainclass
166 = terrain_class_by_name(value, fc_strcasecmp);
167 if (terrain_class_is_valid(source.value.terrainclass)) {
168 return source;
170 break;
171 case VUT_BASE:
172 source.value.base = base_type_by_rule_name(value);
173 if (source.value.base != NULL) {
174 return source;
176 break;
177 case VUT_ROAD:
178 source.value.road = road_type_by_rule_name(value);
179 if (source.value.road != NULL) {
180 return source;
182 break;
183 case VUT_MINYEAR:
184 source.value.minyear = atoi(value);
185 return source;
186 case VUT_TERRAINALTER:
187 source.value.terrainalter
188 = terrain_alteration_by_name(value, fc_strcasecmp);
189 if (terrain_alteration_is_valid(source.value.terrainalter)) {
190 return source;
192 break;
193 case VUT_CITYTILE:
194 source.value.citytile = citytile_by_rule_name(value);
195 if (source.value.citytile != CITYT_LAST) {
196 return source;
198 break;
199 case VUT_COUNT:
200 break;
203 /* If we reach here there's been an error. */
204 source.kind = universals_n_invalid();
205 return source;
208 /**************************************************************************
209 Combine values into a universal structure. This is for serialization
210 and is the opposite of universal_extraction().
211 FIXME: ensure that every caller checks error return!
212 **************************************************************************/
213 struct universal universal_by_number(const enum universals_n kind,
214 const int value)
216 struct universal source;
218 source.kind = kind;
220 switch (source.kind) {
221 case VUT_NONE:
222 /* Avoid compiler warning about unitialized source.value */
223 source.value.advance = NULL;
225 return source;
226 case VUT_ADVANCE:
227 source.value.advance = advance_by_number(value);
228 if (source.value.advance != NULL) {
229 return source;
231 break;
232 case VUT_TECHFLAG:
233 source.value.techflag = value;
234 return source;
235 case VUT_GOVERNMENT:
236 source.value.govern = government_by_number(value);
237 if (source.value.govern != NULL) {
238 return source;
240 break;
241 case VUT_IMPROVEMENT:
242 source.value.building = improvement_by_number(value);
243 if (source.value.building != NULL) {
244 return source;
246 break;
247 case VUT_SPECIAL:
248 source.value.special = value;
249 return source;
250 case VUT_TERRAIN:
251 source.value.terrain = terrain_by_number(value);
252 if (source.value.terrain != NULL) {
253 return source;
255 break;
256 case VUT_TERRFLAG:
257 source.value.terrainflag = value;
258 return source;
259 case VUT_RESOURCE:
260 source.value.resource = resource_by_number(value);
261 if (source.value.resource != NULL) {
262 return source;
264 break;
265 case VUT_NATION:
266 source.value.nation = nation_by_number(value);
267 if (source.value.nation != NULL) {
268 return source;
270 break;
271 case VUT_NATIONALITY:
272 source.value.nationality = nation_by_number(value);
273 if (source.value.nationality != NULL) {
274 return source;
276 break;
277 case VUT_UTYPE:
278 source.value.utype = utype_by_number(value);
279 if (source.value.utype != NULL) {
280 return source;
282 break;
283 case VUT_UTFLAG:
284 source.value.unitflag = value;
285 return source;
286 case VUT_UCLASS:
287 source.value.uclass = uclass_by_number(value);
288 if (source.value.uclass != NULL) {
289 return source;
291 break;
292 case VUT_UCFLAG:
293 source.value.unitclassflag = value;
294 return source;
295 case VUT_OTYPE:
296 source.value.outputtype = value;
297 return source;
298 case VUT_SPECIALIST:
299 source.value.specialist = specialist_by_number(value);
300 return source;
301 case VUT_MINSIZE:
302 source.value.minsize = value;
303 return source;
304 case VUT_AI_LEVEL:
305 source.value.ai_level = value;
306 return source;
307 case VUT_TERRAINCLASS:
308 source.value.terrainclass = value;
309 return source;
310 case VUT_BASE:
311 source.value.base = base_by_number(value);
312 return source;
313 case VUT_ROAD:
314 source.value.road = road_by_number(value);
315 return source;
316 case VUT_MINYEAR:
317 source.value.minyear = value;
318 return source;
319 case VUT_TERRAINALTER:
320 source.value.terrainalter = value;
321 return source;
322 case VUT_CITYTILE:
323 source.value.citytile = value;
324 return source;
325 case VUT_COUNT:
326 break;
329 /* If we reach here there's been an error. */
330 source.kind = universals_n_invalid();
331 /* Avoid compiler warning about unitialized source.value */
332 source.value.advance = NULL;
334 return source;
337 /**************************************************************************
338 Extract universal structure into its components for serialization;
339 the opposite of universal_by_number().
340 **************************************************************************/
341 void universal_extraction(const struct universal *source,
342 int *kind, int *value)
344 *kind = source->kind;
345 *value = universal_number(source);
348 /**************************************************************************
349 Return the universal number of the constituent.
350 **************************************************************************/
351 int universal_number(const struct universal *source)
353 switch (source->kind) {
354 case VUT_NONE:
355 return 0;
356 case VUT_ADVANCE:
357 return advance_number(source->value.advance);
358 case VUT_TECHFLAG:
359 return source->value.techflag;
360 case VUT_GOVERNMENT:
361 return government_number(source->value.govern);
362 case VUT_IMPROVEMENT:
363 return improvement_number(source->value.building);
364 case VUT_SPECIAL:
365 return source->value.special;
366 case VUT_TERRAIN:
367 return terrain_number(source->value.terrain);
368 case VUT_TERRFLAG:
369 return source->value.terrainflag;
370 case VUT_RESOURCE:
371 return resource_number(source->value.resource);
372 case VUT_NATION:
373 return nation_number(source->value.nation);
374 case VUT_NATIONALITY:
375 return nation_number(source->value.nationality);
376 case VUT_UTYPE:
377 return utype_number(source->value.utype);
378 case VUT_UTFLAG:
379 return source->value.unitflag;
380 case VUT_UCLASS:
381 return uclass_number(source->value.uclass);
382 case VUT_UCFLAG:
383 return source->value.unitclassflag;
384 case VUT_OTYPE:
385 return source->value.outputtype;
386 case VUT_SPECIALIST:
387 return specialist_number(source->value.specialist);
388 case VUT_MINSIZE:
389 return source->value.minsize;
390 case VUT_AI_LEVEL:
391 return source->value.ai_level;
392 case VUT_TERRAINCLASS:
393 return source->value.terrainclass;
394 case VUT_BASE:
395 return base_number(source->value.base);
396 case VUT_ROAD:
397 return road_number(source->value.road);
398 case VUT_MINYEAR:
399 return source->value.minyear;
400 case VUT_TERRAINALTER:
401 return source->value.terrainalter;
402 case VUT_CITYTILE:
403 return source->value.citytile;
404 case VUT_COUNT:
405 break;
408 /* If we reach here there's been an error. */
409 fc_assert_msg(FALSE, "universal_number(): invalid source kind %d.",
410 source->kind);
411 return 0;
414 /****************************************************************************
415 Parse a requirement type and value string into a requrement structure.
416 Returns the invalid element for enum universal_n on error. Passing in a
417 NULL type is considered VUT_NONE (not an error).
419 Pass this some values like "Building", "Factory".
420 ****************************************************************************/
421 struct requirement req_from_str(const char *type, const char *range,
422 bool survives, bool negated,
423 const char *value)
425 struct requirement req;
426 bool invalid = TRUE;
427 const char *error = NULL;
429 req.source = universal_by_rule_name(type, value);
431 /* Scan the range string to find the range. If no range is given a
432 * default fallback is used rather than giving an error. */
433 req.range = req_range_by_name(range, fc_strcasecmp);
434 if (!req_range_is_valid(req.range)) {
435 switch (req.source.kind) {
436 case VUT_NONE:
437 case VUT_COUNT:
438 break;
439 case VUT_IMPROVEMENT:
440 case VUT_SPECIAL:
441 case VUT_TERRAIN:
442 case VUT_TERRFLAG:
443 case VUT_RESOURCE:
444 case VUT_UTYPE:
445 case VUT_UTFLAG:
446 case VUT_UCLASS:
447 case VUT_UCFLAG:
448 case VUT_OTYPE:
449 case VUT_SPECIALIST:
450 case VUT_TERRAINCLASS:
451 case VUT_BASE:
452 case VUT_ROAD:
453 case VUT_TERRAINALTER:
454 case VUT_CITYTILE:
455 req.range = REQ_RANGE_LOCAL;
456 break;
457 case VUT_MINSIZE:
458 case VUT_NATIONALITY:
459 req.range = REQ_RANGE_CITY;
460 break;
461 case VUT_GOVERNMENT:
462 case VUT_ADVANCE:
463 case VUT_TECHFLAG:
464 case VUT_NATION:
465 case VUT_AI_LEVEL:
466 req.range = REQ_RANGE_PLAYER;
467 break;
468 case VUT_MINYEAR:
469 req.range = REQ_RANGE_WORLD;
470 break;
474 req.survives = survives;
475 req.negated = negated;
477 /* These checks match what combinations are supported inside
478 * is_req_active(). However, it's only possible to do basic checks,
479 * not anything that might depend on the rest of the ruleset which
480 * might not have been lodaed yet. */
481 switch (req.source.kind) {
482 case VUT_TERRAIN:
483 case VUT_SPECIAL:
484 case VUT_RESOURCE:
485 case VUT_TERRAINCLASS:
486 case VUT_TERRFLAG:
487 case VUT_BASE:
488 case VUT_ROAD:
489 invalid = (req.range != REQ_RANGE_LOCAL
490 && req.range != REQ_RANGE_CADJACENT
491 && req.range != REQ_RANGE_ADJACENT
492 && req.range != REQ_RANGE_CITY);
493 break;
494 case VUT_ADVANCE:
495 case VUT_TECHFLAG:
496 invalid = (req.range < REQ_RANGE_PLAYER);
497 break;
498 case VUT_GOVERNMENT:
499 case VUT_AI_LEVEL:
500 invalid = (req.range != REQ_RANGE_PLAYER);
501 break;
502 case VUT_MINSIZE:
503 case VUT_NATIONALITY:
504 invalid = (req.range != REQ_RANGE_CITY);
505 break;
506 case VUT_NATION:
507 invalid = (req.range != REQ_RANGE_PLAYER
508 && req.range != REQ_RANGE_WORLD);
509 break;
510 case VUT_UTYPE:
511 case VUT_UTFLAG:
512 case VUT_UCLASS:
513 case VUT_UCFLAG:
514 case VUT_OTYPE:
515 case VUT_SPECIALIST:
516 case VUT_TERRAINALTER: /* XXX could in principle support C/ADJACENT */
517 invalid = (req.range != REQ_RANGE_LOCAL);
518 break;
519 case VUT_CITYTILE:
520 invalid = (req.range != REQ_RANGE_LOCAL
521 && req.range != REQ_RANGE_CADJACENT
522 && req.range != REQ_RANGE_ADJACENT);
523 break;
524 case VUT_MINYEAR:
525 invalid = (req.range != REQ_RANGE_WORLD);
526 break;
527 case VUT_IMPROVEMENT:
528 /* Valid ranges depend on the building genus (wonder/improvement),
529 * which might not have been loaded from the ruleset yet.
530 * So we allow anything here, and do a proper check once ruleset
531 * loading is complete, in sanity_check_req_individual(). */
532 case VUT_NONE:
533 invalid = FALSE;
534 break;
535 case VUT_COUNT:
536 break;
539 if (invalid) {
540 error = "bad range";
541 } else {
542 /* Check 'survives'. */
543 switch (req.source.kind) {
544 case VUT_IMPROVEMENT:
545 /* See count_buildings_in_range(). */
546 invalid = survives && req.range <= REQ_RANGE_CONTINENT;
547 break;
548 case VUT_NATION:
549 invalid = survives && req.range != REQ_RANGE_WORLD;
550 break;
551 case VUT_ADVANCE:
552 case VUT_GOVERNMENT:
553 case VUT_TERRAIN:
554 case VUT_SPECIAL:
555 case VUT_UTYPE:
556 case VUT_UTFLAG:
557 case VUT_UCLASS:
558 case VUT_UCFLAG:
559 case VUT_OTYPE:
560 case VUT_SPECIALIST:
561 case VUT_MINSIZE:
562 case VUT_AI_LEVEL:
563 case VUT_TERRAINCLASS:
564 case VUT_BASE:
565 case VUT_MINYEAR:
566 case VUT_TERRAINALTER:
567 case VUT_CITYTILE:
568 case VUT_ROAD:
569 case VUT_RESOURCE:
570 case VUT_TERRFLAG:
571 case VUT_NATIONALITY:
572 case VUT_TECHFLAG:
573 /* Most requirements don't support 'survives'. */
574 invalid = survives;
575 break;
576 case VUT_NONE:
577 case VUT_COUNT:
578 break;
580 if (invalid) {
581 error = "bad 'survives'";
585 if (invalid) {
586 log_error("Invalid requirement %s | %s | %s | %s | %s: %s",
587 type, range, survives ? "survives" : "",
588 negated ? "negated" : "", value, error);
589 req.source.kind = universals_n_invalid();
592 return req;
595 /****************************************************************************
596 Set the values of a req from serializable integers. This is the opposite
597 of req_get_values.
598 ****************************************************************************/
599 struct requirement req_from_values(int type, int range,
600 bool survives, bool negated,
601 int value)
603 struct requirement req;
605 req.source = universal_by_number(type, value);
606 req.range = range;
607 req.survives = survives;
608 req.negated = negated;
609 return req;
612 /****************************************************************************
613 Return the value of a req as a serializable integer. This is the opposite
614 of req_set_value.
615 ****************************************************************************/
616 void req_get_values(const struct requirement *req,
617 int *type, int *range,
618 bool *survives, bool *negated,
619 int *value)
621 universal_extraction(&req->source, type, value);
622 *range = req->range;
623 *survives = req->survives;
624 *negated = req->negated;
627 /****************************************************************************
628 Returns TRUE if req1 and req2 are equal.
629 ****************************************************************************/
630 bool are_requirements_equal(const struct requirement *req1,
631 const struct requirement *req2)
633 return (are_universals_equal(&req1->source, &req2->source)
634 && req1->range == req2->range
635 && req1->survives == req2->survives
636 && req1->negated == req2->negated);
639 /****************************************************************************
640 Returns TRUE if req1 and req2 directly negate each other.
641 ****************************************************************************/
642 bool are_requirements_opposites(const struct requirement *req1,
643 const struct requirement *req2)
645 return (are_universals_equal(&req1->source, &req2->source)
646 && req1->range == req2->range
647 && req1->survives == req2->survives
648 && req1->negated != req2->negated);
651 /****************************************************************************
652 Returns the number of total world buildings (this includes buildings
653 that have been destroyed).
654 ****************************************************************************/
655 static int num_world_buildings_total(const struct impr_type *building)
657 if (is_great_wonder(building)) {
658 return (great_wonder_is_built(building)
659 || great_wonder_is_destroyed(building) ? 1 : 0);
660 } else {
661 log_error("World-ranged requirements are only supported for wonders.");
662 return 0;
666 /****************************************************************************
667 Returns the number of buildings of a certain type in the world.
668 ****************************************************************************/
669 static int num_world_buildings(const struct impr_type *building)
671 if (is_great_wonder(building)) {
672 return (great_wonder_is_built(building) ? 1 : 0);
673 } else {
674 log_error("World-ranged requirements are only supported for wonders.");
675 return 0;
679 /****************************************************************************
680 Returns whether a building of a certain type has ever been built by
681 pplayer, even if it has subsequently been destroyed.
683 Note: the implementation of this is no different in principle from
684 num_world_buildings_total(), but the semantics are different because
685 unlike a great wonder, a small wonder could be destroyed and rebuilt
686 many times, requiring return of values >1, but there's no record kept
687 to support that. Fortunately, the only current caller doesn't need the
688 exact number.
689 ****************************************************************************/
690 static bool player_has_ever_built(const struct player *pplayer,
691 const struct impr_type *building)
693 if (is_wonder(building)) {
694 return (wonder_is_built(pplayer, building)
695 || wonder_is_lost(pplayer, building) ? TRUE : FALSE);
696 } else {
697 log_error("Player-ranged requirements are only supported for wonders.");
698 return FALSE;
702 /****************************************************************************
703 Returns the number of buildings of a certain type owned by plr.
704 ****************************************************************************/
705 static int num_player_buildings(const struct player *pplayer,
706 const struct impr_type *building)
708 if (is_wonder(building)) {
709 return (wonder_is_built(pplayer, building) ? 1 : 0);
710 } else {
711 log_error("Player-ranged requirements are only supported for wonders.");
712 return 0;
716 /****************************************************************************
717 Returns the number of buildings of a certain type on a continent.
718 ****************************************************************************/
719 static int num_continent_buildings(const struct player *pplayer,
720 int continent,
721 const struct impr_type *building)
723 if (is_wonder(building)) {
724 const struct city *pcity;
726 pcity = city_from_wonder(pplayer, building);
727 if (pcity && pcity->tile && tile_continent(pcity->tile) == continent) {
728 return 1;
730 } else {
731 log_error("Island-ranged requirements are only supported for wonders.");
733 return 0;
736 /****************************************************************************
737 Returns the number of buildings of a certain type in a city.
738 ****************************************************************************/
739 static int num_city_buildings(const struct city *pcity,
740 const struct impr_type *building)
742 return (city_has_building(pcity, building) ? 1 : 0);
745 /****************************************************************************
746 Are there any source buildings within range of the target that are not
747 obsolete?
749 The target gives the type of the target. The exact target is a player,
750 city, or building specified by the target_xxx arguments.
752 The range gives the range of the requirement.
754 "Survives" specifies whether the requirement allows destroyed sources.
755 If set then all source buildings ever built are counted; if not then only
756 living buildings are counted.
758 source gives the building type of the source in question.
759 ****************************************************************************/
760 static enum fc_tristate
761 is_building_in_range(const struct player *target_player,
762 const struct city *target_city,
763 const struct impr_type *target_building,
764 enum req_range range,
765 bool survives,
766 const struct impr_type *source)
768 /* Check if it's certain that the building is obsolete given the
769 * specification we have */
770 if (improvement_obsolete(target_player, source)) {
771 return TRI_NO;
774 if (survives) {
776 /* Check whether condition has ever held, using cached information. */
777 switch (range) {
778 case REQ_RANGE_WORLD:
779 return BOOL_TO_TRISTATE(num_world_buildings_total(source) > 0);
780 case REQ_RANGE_PLAYER:
781 if (target_player == NULL) {
782 return TRI_MAYBE;
784 return BOOL_TO_TRISTATE(player_has_ever_built(target_player, source));
785 case REQ_RANGE_CONTINENT:
786 case REQ_RANGE_CITY:
787 case REQ_RANGE_LOCAL:
788 case REQ_RANGE_CADJACENT:
789 case REQ_RANGE_ADJACENT:
790 /* There is no sources cache for this. */
791 log_error("Surviving requirements are only supported at "
792 "world and player ranges.");
793 return TRI_NO;
794 case REQ_RANGE_COUNT:
795 break;
798 } else {
800 /* Non-surviving requirement. */
801 switch (range) {
802 case REQ_RANGE_WORLD:
803 return BOOL_TO_TRISTATE(num_world_buildings(source) > 0);
804 case REQ_RANGE_PLAYER:
805 if (target_player == NULL) {
806 return TRI_MAYBE;
808 return BOOL_TO_TRISTATE(num_player_buildings(target_player, source) > 0);
809 case REQ_RANGE_CONTINENT:
810 /* At present, "Continent" effects can affect only
811 * cities and units in cities. */
812 if (target_player && target_city) {
813 int continent = tile_continent(target_city->tile);
814 return BOOL_TO_TRISTATE(num_continent_buildings(target_player,
815 continent, source) > 0);
816 } else {
817 return TRI_MAYBE;
819 case REQ_RANGE_CITY:
820 if (target_city) {
821 return BOOL_TO_TRISTATE(num_city_buildings(target_city, source) > 0);
822 } else {
823 return TRI_MAYBE;
825 case REQ_RANGE_LOCAL:
826 if (target_building) {
827 if (target_building == source) {
828 return BOOL_TO_TRISTATE(num_city_buildings(target_city, source) > 0);
829 } else {
830 return TRI_NO;
832 } else {
833 /* TODO: other local targets */
834 return TRI_MAYBE;
836 case REQ_RANGE_CADJACENT:
837 case REQ_RANGE_ADJACENT:
838 return TRI_NO;
839 case REQ_RANGE_COUNT:
840 break;
845 fc_assert_msg(FALSE, "Invalid range %d.", range);
846 return TRI_NO;
849 /****************************************************************************
850 Is there a source tech within range of the target?
851 ****************************************************************************/
852 static enum fc_tristate is_tech_in_range(const struct player *target_player,
853 enum req_range range,
854 Tech_type_id tech)
856 switch (range) {
857 case REQ_RANGE_PLAYER:
858 if (NULL != target_player) {
859 return BOOL_TO_TRISTATE(TECH_KNOWN == player_invention_state(target_player, tech));
860 } else {
861 return TRI_MAYBE;
863 case REQ_RANGE_WORLD:
864 return BOOL_TO_TRISTATE(game.info.global_advances[tech]);
865 case REQ_RANGE_LOCAL:
866 case REQ_RANGE_CADJACENT:
867 case REQ_RANGE_ADJACENT:
868 case REQ_RANGE_CITY:
869 case REQ_RANGE_CONTINENT:
870 case REQ_RANGE_COUNT:
871 break;
874 fc_assert_msg(FALSE, "Invalid range %d.", range);
876 return TRI_MAYBE;
879 /****************************************************************************
880 Is there a source special within range of the target?
881 ****************************************************************************/
882 static enum fc_tristate is_special_in_range(const struct tile *target_tile,
883 const struct city *target_city,
884 enum req_range range, bool survives,
885 enum tile_special_type special)
888 switch (range) {
889 case REQ_RANGE_LOCAL:
890 if (!target_tile) {
891 return TRI_MAYBE;
893 return BOOL_TO_TRISTATE(tile_has_special(target_tile, special));
894 case REQ_RANGE_CADJACENT:
895 if (!target_tile) {
896 return TRI_MAYBE;
898 return BOOL_TO_TRISTATE(is_special_card_near(target_tile, special, TRUE));
899 case REQ_RANGE_ADJACENT:
900 if (!target_tile) {
901 return TRI_MAYBE;
903 return BOOL_TO_TRISTATE(is_special_near_tile(target_tile, special, TRUE));
904 case REQ_RANGE_CITY:
905 if (!target_city) {
906 return TRI_MAYBE;
908 city_tile_iterate(city_map_radius_sq_get(target_city),
909 city_tile(target_city), ptile) {
910 if (tile_has_special(ptile, special)) {
911 return TRI_YES;
913 } city_tile_iterate_end;
915 return TRI_NO;
916 case REQ_RANGE_CONTINENT:
917 case REQ_RANGE_PLAYER:
918 case REQ_RANGE_WORLD:
919 case REQ_RANGE_COUNT:
920 break;
923 fc_assert_msg(FALSE, "Invalid range %d.", range);
925 return TRI_MAYBE;
928 /****************************************************************************
929 Is there a source tile within range of the target?
930 ****************************************************************************/
931 static enum fc_tristate is_terrain_in_range(const struct tile *target_tile,
932 const struct city *target_city,
933 enum req_range range, bool survives,
934 const struct terrain *pterrain)
936 switch (range) {
937 case REQ_RANGE_LOCAL:
938 /* The requirement is filled if the tile has the terrain. */
939 if (!target_tile) {
940 return TRI_MAYBE;
942 return BOOL_TO_TRISTATE(pterrain && tile_terrain(target_tile) == pterrain);
943 case REQ_RANGE_CADJACENT:
944 if (!target_tile) {
945 return TRI_MAYBE;
947 return BOOL_TO_TRISTATE(pterrain && is_terrain_card_near(target_tile, pterrain, TRUE));
948 case REQ_RANGE_ADJACENT:
949 if (!target_tile) {
950 return TRI_MAYBE;
952 return BOOL_TO_TRISTATE(pterrain && is_terrain_near_tile(target_tile, pterrain, TRUE));
953 case REQ_RANGE_CITY:
954 if (!target_city) {
955 return TRI_MAYBE;
957 if (pterrain != NULL) {
958 city_tile_iterate(city_map_radius_sq_get(target_city),
959 city_tile(target_city), ptile) {
960 if (tile_terrain(ptile) == pterrain) {
961 return TRI_YES;
963 } city_tile_iterate_end;
966 return TRI_NO;
967 case REQ_RANGE_CONTINENT:
968 case REQ_RANGE_PLAYER:
969 case REQ_RANGE_WORLD:
970 case REQ_RANGE_COUNT:
971 break;
974 fc_assert_msg(FALSE, "Invalid range %d.", range);
976 return TRI_MAYBE;
979 /****************************************************************************
980 Is there a source tile within range of the target?
981 ****************************************************************************/
982 static enum fc_tristate is_resource_in_range(const struct tile *target_tile,
983 const struct city *target_city,
984 enum req_range range, bool survives,
985 const struct resource *pres)
987 switch (range) {
988 case REQ_RANGE_LOCAL:
989 if (!target_tile) {
990 return TRI_MAYBE;
992 /* The requirement is filled if the tile has the terrain. */
993 return BOOL_TO_TRISTATE(pres && tile_resource(target_tile) == pres);
994 case REQ_RANGE_CADJACENT:
995 if (!target_tile) {
996 return TRI_MAYBE;
998 return BOOL_TO_TRISTATE(pres && is_resource_card_near(target_tile, pres, TRUE));
999 case REQ_RANGE_ADJACENT:
1000 if (!target_tile) {
1001 return TRI_MAYBE;
1003 return BOOL_TO_TRISTATE(pres && is_resource_near_tile(target_tile, pres, TRUE));
1004 case REQ_RANGE_CITY:
1005 if (!target_city) {
1006 return TRI_MAYBE;
1008 if (pres != NULL) {
1009 city_tile_iterate(city_map_radius_sq_get(target_city),
1010 city_tile(target_city), ptile) {
1011 if (tile_resource(ptile) == pres) {
1012 return TRI_YES;
1014 } city_tile_iterate_end;
1017 return TRI_NO;
1018 case REQ_RANGE_CONTINENT:
1019 case REQ_RANGE_PLAYER:
1020 case REQ_RANGE_WORLD:
1021 case REQ_RANGE_COUNT:
1022 break;
1025 fc_assert_msg(FALSE, "Invalid range %d.", range);
1027 return TRI_MAYBE;
1030 /****************************************************************************
1031 Is there a source terrain class within range of the target?
1032 ****************************************************************************/
1033 static enum fc_tristate is_terrain_class_in_range(const struct tile *target_tile,
1034 const struct city *target_city,
1035 enum req_range range, bool survives,
1036 enum terrain_class pclass)
1038 switch (range) {
1039 case REQ_RANGE_LOCAL:
1040 /* The requirement is filled if the tile has the terrain of correct class. */
1041 if (!target_tile) {
1042 return TRI_MAYBE;
1044 return BOOL_TO_TRISTATE(terrain_type_terrain_class(tile_terrain(target_tile)) == pclass);
1045 case REQ_RANGE_CADJACENT:
1046 if (!target_tile) {
1047 return TRI_MAYBE;
1049 return BOOL_TO_TRISTATE(is_terrain_class_card_near(target_tile, pclass));
1050 case REQ_RANGE_ADJACENT:
1051 if (!target_tile) {
1052 return TRI_MAYBE;
1054 return BOOL_TO_TRISTATE(is_terrain_class_near_tile(target_tile, pclass));
1055 case REQ_RANGE_CITY:
1056 if (!target_city) {
1057 return TRI_MAYBE;
1059 city_tile_iterate(city_map_radius_sq_get(target_city),
1060 city_tile(target_city), ptile) {
1061 if (terrain_type_terrain_class(tile_terrain(ptile)) == pclass) {
1062 return TRI_YES;
1064 } city_tile_iterate_end;
1066 return TRI_NO;
1067 case REQ_RANGE_CONTINENT:
1068 case REQ_RANGE_PLAYER:
1069 case REQ_RANGE_WORLD:
1070 case REQ_RANGE_COUNT:
1071 break;
1074 fc_assert_msg(FALSE, "Invalid range %d.", range);
1076 return TRI_MAYBE;
1079 /****************************************************************************
1080 Is there a terrain with the given flag within range of the target?
1081 ****************************************************************************/
1082 static enum fc_tristate is_terrainflag_in_range(const struct tile *target_tile,
1083 const struct city *target_city,
1084 enum req_range range, bool survives,
1085 enum terrain_flag_id terrflag)
1087 switch (range) {
1088 case REQ_RANGE_LOCAL:
1089 /* The requirement is filled if the tile has the terrain with correct flag. */
1090 if (!target_tile) {
1091 return TRI_MAYBE;
1093 return BOOL_TO_TRISTATE(terrain_has_flag(tile_terrain(target_tile), terrflag));
1094 case REQ_RANGE_CADJACENT:
1095 if (!target_tile) {
1096 return TRI_MAYBE;
1098 return BOOL_TO_TRISTATE(is_terrain_flag_card_near(target_tile, terrflag));
1099 case REQ_RANGE_ADJACENT:
1100 if (!target_tile) {
1101 return TRI_MAYBE;
1103 return BOOL_TO_TRISTATE(is_terrain_flag_near_tile(target_tile, terrflag));
1104 case REQ_RANGE_CITY:
1105 if (!target_city) {
1106 return TRI_MAYBE;
1108 city_tile_iterate(city_map_radius_sq_get(target_city),
1109 city_tile(target_city), ptile) {
1110 if (terrain_has_flag(tile_terrain(ptile), terrflag)) {
1111 return TRI_YES;
1113 } city_tile_iterate_end;
1115 return TRI_NO;
1116 case REQ_RANGE_CONTINENT:
1117 case REQ_RANGE_PLAYER:
1118 case REQ_RANGE_WORLD:
1119 case REQ_RANGE_COUNT:
1120 break;
1123 fc_assert_msg(FALSE, "Invalid range %d.", range);
1125 return TRI_MAYBE;
1128 /****************************************************************************
1129 Is there a source base type within range of the target?
1130 ****************************************************************************/
1131 static enum fc_tristate is_base_type_in_range(const struct tile *target_tile,
1132 const struct city *target_city,
1133 enum req_range range, bool survives,
1134 struct base_type *pbase)
1136 switch (range) {
1137 case REQ_RANGE_LOCAL:
1138 /* The requirement is filled if the tile has base of requested type. */
1139 if (!target_tile) {
1140 return TRI_MAYBE;
1142 return BOOL_TO_TRISTATE(tile_has_base(target_tile, pbase));
1143 case REQ_RANGE_CADJACENT:
1144 if (!target_tile) {
1145 return TRI_MAYBE;
1147 return BOOL_TO_TRISTATE(is_base_card_near(target_tile, pbase));
1148 case REQ_RANGE_ADJACENT:
1149 if (!target_tile) {
1150 return TRI_MAYBE;
1152 return BOOL_TO_TRISTATE(is_base_near_tile(target_tile, pbase));
1153 case REQ_RANGE_CITY:
1154 if (!target_city) {
1155 return TRI_MAYBE;
1157 city_tile_iterate(city_map_radius_sq_get(target_city),
1158 city_tile(target_city), ptile) {
1159 if (tile_has_base(ptile, pbase)) {
1160 return TRI_YES;
1162 } city_tile_iterate_end;
1164 return TRI_NO;
1165 case REQ_RANGE_CONTINENT:
1166 case REQ_RANGE_PLAYER:
1167 case REQ_RANGE_WORLD:
1168 case REQ_RANGE_COUNT:
1169 break;
1172 fc_assert_msg(FALSE, "Invalid range %d.", range);
1174 return TRI_MAYBE;
1177 /****************************************************************************
1178 Is there a tech with the given flag within range of the target?
1179 ****************************************************************************/
1180 static enum fc_tristate is_techflag_in_range(const struct player *target_player,
1181 enum req_range range,
1182 enum tech_flag_id techflag)
1184 switch (range) {
1185 case REQ_RANGE_PLAYER:
1186 if (NULL != target_player) {
1187 return BOOL_TO_TRISTATE(player_knows_techs_with_flag(target_player, techflag));
1188 } else {
1189 return TRI_MAYBE;
1191 break;
1192 case REQ_RANGE_WORLD:
1193 players_iterate(pplayer) {
1194 if (player_knows_techs_with_flag(pplayer, techflag)) {
1195 return TRI_YES;
1197 } players_iterate_end;
1199 return TRI_NO;
1200 case REQ_RANGE_LOCAL:
1201 case REQ_RANGE_CADJACENT:
1202 case REQ_RANGE_ADJACENT:
1203 case REQ_RANGE_CITY:
1204 case REQ_RANGE_CONTINENT:
1205 case REQ_RANGE_COUNT:
1206 break;
1209 fc_assert_msg(FALSE, "Invalid range %d.", range);
1211 return TRI_MAYBE;
1214 /****************************************************************************
1215 Is there a source road type within range of the target?
1216 ****************************************************************************/
1217 static enum fc_tristate is_road_type_in_range(const struct tile *target_tile,
1218 const struct city *target_city,
1219 enum req_range range, bool survives,
1220 struct road_type *proad)
1222 switch (range) {
1223 case REQ_RANGE_LOCAL:
1224 /* The requirement is filled if the tile has road of requested type. */
1225 if (!target_tile) {
1226 return TRI_MAYBE;
1228 return BOOL_TO_TRISTATE(tile_has_road(target_tile, proad));
1229 case REQ_RANGE_CADJACENT:
1230 if (!target_tile) {
1231 return TRI_MAYBE;
1233 return BOOL_TO_TRISTATE(is_road_card_near(target_tile, proad));
1234 case REQ_RANGE_ADJACENT:
1235 if (!target_tile) {
1236 return TRI_MAYBE;
1238 return BOOL_TO_TRISTATE(is_road_near_tile(target_tile, proad));
1239 case REQ_RANGE_CITY:
1240 if (!target_city) {
1241 return TRI_MAYBE;
1243 city_tile_iterate(city_map_radius_sq_get(target_city),
1244 city_tile(target_city), ptile) {
1245 if (tile_has_road(ptile, proad)) {
1246 return TRI_YES;
1248 } city_tile_iterate_end;
1250 return TRI_NO;
1251 case REQ_RANGE_CONTINENT:
1252 case REQ_RANGE_PLAYER:
1253 case REQ_RANGE_WORLD:
1254 case REQ_RANGE_COUNT:
1255 break;
1258 fc_assert_msg(FALSE, "Invalid range %d.", range);
1260 return TRI_MAYBE;
1263 /****************************************************************************
1264 Is there a terrain which can support the specified infrastructure
1265 within range of the target?
1266 ****************************************************************************/
1267 static enum fc_tristate is_terrain_alter_possible_in_range(const struct tile *target_tile,
1268 enum req_range range,
1269 bool survives,
1270 enum terrain_alteration alteration)
1272 if (!target_tile) {
1273 return TRI_MAYBE;
1276 switch (range) {
1277 case REQ_RANGE_LOCAL:
1278 return BOOL_TO_TRISTATE(terrain_can_support_alteration(tile_terrain(target_tile),
1279 alteration));
1280 case REQ_RANGE_CADJACENT:
1281 case REQ_RANGE_ADJACENT: /* XXX Could in principle support ADJACENT. */
1282 case REQ_RANGE_CITY:
1283 case REQ_RANGE_CONTINENT:
1284 case REQ_RANGE_PLAYER:
1285 case REQ_RANGE_WORLD:
1286 case REQ_RANGE_COUNT:
1287 break;
1290 fc_assert_msg(FALSE, "Invalid range %d.", range);
1292 return TRI_MAYBE;
1295 /****************************************************************************
1296 Is there a nation within range of the target?
1297 ****************************************************************************/
1298 static enum fc_tristate is_nation_in_range(const struct player *target_player,
1299 enum req_range range, bool survives,
1300 const struct nation_type *nation)
1302 switch (range) {
1303 case REQ_RANGE_PLAYER:
1304 if (target_player == NULL) {
1305 return TRI_MAYBE;
1307 return BOOL_TO_TRISTATE(nation_of_player(target_player) == nation);
1308 case REQ_RANGE_WORLD:
1309 /* NB: if a player is ever removed outright from the game
1310 * (e.g. via /remove), rather than just dying, this 'survives'
1311 * requirement will stop being true for their nation.
1312 * create_command_newcomer() can also cause this to happen. */
1313 return BOOL_TO_TRISTATE(NULL != nation->player
1314 && (survives || nation->player->is_alive));
1315 case REQ_RANGE_LOCAL:
1316 case REQ_RANGE_CADJACENT:
1317 case REQ_RANGE_ADJACENT:
1318 case REQ_RANGE_CITY:
1319 case REQ_RANGE_CONTINENT:
1320 case REQ_RANGE_COUNT:
1321 break;
1324 fc_assert_msg(FALSE, "Invalid range %d.", range);
1326 return TRI_MAYBE;
1329 /****************************************************************************
1330 Is there a nationality within range of the target?
1331 ****************************************************************************/
1332 static enum fc_tristate is_nationality_in_range(const struct city *target_city,
1333 enum req_range range,
1334 const struct nation_type *nationality)
1336 switch (range) {
1337 case REQ_RANGE_CITY:
1338 if (target_city == NULL) {
1339 return TRI_MAYBE;
1341 citizens_iterate(target_city, slot, count) {
1342 if (player_slot_get_player(slot)->nation == nationality) {
1343 return TRI_YES;
1345 } citizens_iterate_end;
1347 return TRI_NO;
1348 case REQ_RANGE_PLAYER:
1349 case REQ_RANGE_WORLD:
1350 case REQ_RANGE_LOCAL:
1351 case REQ_RANGE_CADJACENT:
1352 case REQ_RANGE_ADJACENT:
1353 case REQ_RANGE_CONTINENT:
1354 case REQ_RANGE_COUNT:
1355 break;
1358 fc_assert_msg(FALSE, "Invalid range %d.", range);
1360 return TRI_MAYBE;
1363 /****************************************************************************
1364 Is there a unit of the given type within range of the target?
1365 ****************************************************************************/
1366 static enum fc_tristate is_unittype_in_range(const struct unit_type *target_unittype,
1367 enum req_range range, bool survives,
1368 struct unit_type *punittype)
1370 /* If no target_unittype is given, we allow the req to be met. This is
1371 * to allow querying of certain effect types (like the presence of city
1372 * walls) without actually knowing the target unit. */
1373 return BOOL_TO_TRISTATE(range == REQ_RANGE_LOCAL
1374 && (!target_unittype
1375 || target_unittype == punittype));
1378 /****************************************************************************
1379 Is there a unit with the given flag within range of the target?
1380 ****************************************************************************/
1381 static enum fc_tristate is_unitflag_in_range(const struct unit_type *target_unittype,
1382 enum req_range range, bool survives,
1383 enum unit_type_flag_id unitflag)
1385 /* If no target_unittype is given, we allow the req to be met. This is
1386 * to allow querying of certain effect types (like the presence of city
1387 * walls) without actually knowing the target unit. */
1388 if (range != REQ_RANGE_LOCAL) {
1389 return TRI_NO;
1391 if (!target_unittype) {
1392 return TRI_MAYBE;
1395 return BOOL_TO_TRISTATE(utype_has_flag(target_unittype, unitflag));
1398 /****************************************************************************
1399 Is there a unit with the given flag within range of the target?
1400 ****************************************************************************/
1401 static enum fc_tristate is_unitclass_in_range(const struct unit_type *target_unittype,
1402 enum req_range range, bool survives,
1403 struct unit_class *pclass)
1405 /* If no target_unittype is given, we allow the req to be met. This is
1406 * to allow querying of certain effect types (like the presence of city
1407 * walls) without actually knowing the target unit. */
1408 return BOOL_TO_TRISTATE(range == REQ_RANGE_LOCAL
1409 && (!target_unittype
1410 || utype_class(target_unittype) == pclass));
1413 /****************************************************************************
1414 Is there a unit with the given flag within range of the target?
1415 ****************************************************************************/
1416 static enum fc_tristate is_unitclassflag_in_range(const struct unit_type *target_unittype,
1417 enum req_range range, bool survives,
1418 enum unit_class_flag_id ucflag)
1420 /* If no target_unittype is given, we allow the req to be met. This is
1421 * to allow querying of certain effect types (like the presence of city
1422 * walls) without actually knowing the target unit. */
1423 return BOOL_TO_TRISTATE(range == REQ_RANGE_LOCAL
1424 && (!target_unittype
1425 || uclass_has_flag(utype_class(target_unittype), ucflag)));
1428 /****************************************************************************
1429 Is center of given city in tile. If city is NULL, any city will do.
1430 ****************************************************************************/
1431 static bool is_city_in_tile(const struct tile *ptile,
1432 const struct city *pcity)
1434 if (pcity == NULL) {
1435 return tile_city(ptile) != NULL;
1436 } else {
1437 return is_city_center(pcity, ptile);
1441 /****************************************************************************
1442 Is center of given city in range. If city is NULL, any city will do.
1443 ****************************************************************************/
1444 static enum fc_tristate is_citytile_in_range(const struct tile *target_tile,
1445 const struct city *target_city,
1446 enum req_range range,
1447 enum citytile_type citytile)
1449 if (target_tile) {
1450 if (citytile == CITYT_CENTER) {
1451 switch (range) {
1452 case REQ_RANGE_LOCAL:
1453 return BOOL_TO_TRISTATE(is_city_in_tile(target_tile, target_city));
1454 case REQ_RANGE_CADJACENT:
1455 cardinal_adjc_iterate(target_tile, adjc_tile) {
1456 if (is_city_in_tile(adjc_tile, target_city)) {
1457 return TRI_YES;
1459 } cardinal_adjc_iterate_end;
1461 return TRI_NO;
1462 case REQ_RANGE_ADJACENT:
1463 adjc_iterate(target_tile, adjc_tile) {
1464 if (is_city_in_tile(adjc_tile, target_city)) {
1465 return TRI_YES;
1467 } adjc_iterate_end;
1469 return TRI_NO;
1470 case REQ_RANGE_CITY:
1471 case REQ_RANGE_CONTINENT:
1472 case REQ_RANGE_PLAYER:
1473 case REQ_RANGE_WORLD:
1474 case REQ_RANGE_COUNT:
1475 break;
1478 fc_assert_msg(FALSE, "Invalid range %d for citytile.", range);
1480 return TRI_MAYBE;
1481 } else {
1482 /* Not implemented */
1483 log_error("is_req_active(): citytile %d not supported.",
1484 citytile);
1485 return TRI_MAYBE;
1487 } else {
1488 return TRI_MAYBE;
1492 /****************************************************************************
1493 Checks the requirement to see if it is active on the given target.
1495 target gives the type of the target
1496 (player,city,building,tile) give the exact target
1497 req gives the requirement itself
1499 Make sure you give all aspects of the target when calling this function:
1500 for instance if you have TARGET_CITY pass the city's owner as the target
1501 player as well as the city itself as the target city.
1502 ****************************************************************************/
1503 bool is_req_active(const struct player *target_player,
1504 const struct city *target_city,
1505 const struct impr_type *target_building,
1506 const struct tile *target_tile,
1507 const struct unit_type *target_unittype,
1508 const struct output_type *target_output,
1509 const struct specialist *target_specialist,
1510 const struct requirement *req,
1511 const enum req_problem_type prob_type)
1513 enum fc_tristate eval = TRI_NO;
1515 /* Note the target may actually not exist. In particular, effects that
1516 * have a VUT_SPECIAL, VUT_RESOURCE, or VUT_TERRAIN may often be passed
1517 * to this function with a city as their target. In this case the
1518 * requirement is simply not met. */
1519 switch (req->source.kind) {
1520 case VUT_NONE:
1521 eval = TRI_YES;
1522 break;
1523 case VUT_ADVANCE:
1524 /* The requirement is filled if the player owns the tech. */
1525 eval = is_tech_in_range(target_player, req->range,
1526 advance_number(req->source.value.advance));
1527 break;
1528 case VUT_TECHFLAG:
1529 eval = is_techflag_in_range(target_player, req->range,
1530 req->source.value.techflag);
1531 break;
1532 case VUT_GOVERNMENT:
1533 /* The requirement is filled if the player is using the government. */
1534 if (target_player == NULL) {
1535 eval = TRI_MAYBE;
1536 } else {
1537 eval = BOOL_TO_TRISTATE(government_of_player(target_player) == req->source.value.govern);
1539 break;
1540 case VUT_IMPROVEMENT:
1541 eval = is_building_in_range(target_player, target_city,
1542 target_building,
1543 req->range, req->survives,
1544 req->source.value.building);
1545 break;
1546 case VUT_SPECIAL:
1547 eval = is_special_in_range(target_tile, target_city,
1548 req->range, req->survives,
1549 req->source.value.special);
1550 break;
1551 case VUT_TERRAIN:
1552 eval = is_terrain_in_range(target_tile, target_city,
1553 req->range, req->survives,
1554 req->source.value.terrain);
1555 break;
1556 case VUT_TERRFLAG:
1557 eval = is_terrainflag_in_range(target_tile, target_city,
1558 req->range, req->survives,
1559 req->source.value.terrainflag);
1560 break;
1561 case VUT_RESOURCE:
1562 eval = is_resource_in_range(target_tile, target_city,
1563 req->range, req->survives,
1564 req->source.value.resource);
1565 break;
1566 case VUT_NATION:
1567 eval = is_nation_in_range(target_player, req->range, req->survives,
1568 req->source.value.nation);
1569 break;
1570 case VUT_NATIONALITY:
1571 eval = is_nationality_in_range(target_city, req->range,
1572 req->source.value.nationality);
1573 break;
1574 case VUT_UTYPE:
1575 if (target_unittype == NULL) {
1576 eval = TRI_MAYBE;
1577 } else {
1578 eval = is_unittype_in_range(target_unittype,
1579 req->range, req->survives,
1580 req->source.value.utype);
1582 break;
1583 case VUT_UTFLAG:
1584 eval = is_unitflag_in_range(target_unittype,
1585 req->range, req->survives,
1586 req->source.value.unitflag);
1587 break;
1588 case VUT_UCLASS:
1589 if (target_unittype == NULL) {
1590 eval = TRI_MAYBE;
1591 } else {
1592 eval = is_unitclass_in_range(target_unittype,
1593 req->range, req->survives,
1594 req->source.value.uclass);
1596 break;
1597 case VUT_UCFLAG:
1598 if (target_unittype == NULL) {
1599 eval = TRI_MAYBE;
1600 } else {
1601 eval = is_unitclassflag_in_range(target_unittype,
1602 req->range, req->survives,
1603 req->source.value.unitclassflag);
1605 break;
1606 case VUT_OTYPE:
1607 eval = BOOL_TO_TRISTATE(target_output
1608 && target_output->index == req->source.value.outputtype);
1609 break;
1610 case VUT_SPECIALIST:
1611 eval = BOOL_TO_TRISTATE(target_specialist
1612 && target_specialist == req->source.value.specialist);
1613 break;
1614 case VUT_MINSIZE:
1615 if (target_city == NULL) {
1616 eval = TRI_MAYBE;
1617 } else {
1618 eval = BOOL_TO_TRISTATE(city_size_get(target_city) >= req->source.value.minsize);
1620 break;
1621 case VUT_AI_LEVEL:
1622 if (target_player == NULL) {
1623 eval = TRI_MAYBE;
1624 } else {
1625 eval = BOOL_TO_TRISTATE(target_player->ai_controlled
1626 && target_player->ai_common.skill_level == req->source.value.ai_level);
1628 break;
1629 case VUT_TERRAINCLASS:
1630 eval = is_terrain_class_in_range(target_tile, target_city,
1631 req->range, req->survives,
1632 req->source.value.terrainclass);
1633 break;
1634 case VUT_BASE:
1635 eval = is_base_type_in_range(target_tile, target_city,
1636 req->range, req->survives,
1637 req->source.value.base);
1638 break;
1639 case VUT_ROAD:
1640 eval = is_road_type_in_range(target_tile, target_city,
1641 req->range, req->survives,
1642 req->source.value.road);
1643 break;
1644 case VUT_MINYEAR:
1645 eval = BOOL_TO_TRISTATE(game.info.year >= req->source.value.minyear);
1646 break;
1647 case VUT_TERRAINALTER:
1648 if (target_tile == NULL) {
1649 eval = TRI_MAYBE;
1650 } else {
1651 eval = is_terrain_alter_possible_in_range(target_tile,
1652 req->range, req->survives,
1653 req->source.value.terrainalter);
1655 break;
1656 case VUT_CITYTILE:
1657 if (target_tile == NULL) {
1658 eval = TRI_MAYBE;
1659 } else {
1660 eval = is_citytile_in_range(target_tile, target_city,
1661 req->range,
1662 req->source.value.citytile);
1664 break;
1665 case VUT_COUNT:
1666 log_error("is_req_active(): invalid source kind %d.", req->source.kind);
1667 return FALSE;
1670 if (eval == TRI_MAYBE) {
1671 if (prob_type == RPT_POSSIBLE) {
1672 return TRUE;
1673 } else {
1674 return FALSE;
1678 if (req->negated) {
1679 return (eval == TRI_NO);
1680 } else {
1681 return (eval == TRI_YES);
1685 /****************************************************************************
1686 Checks the requirement(s) to see if they are active on the given target.
1688 target gives the type of the target
1689 (player,city,building,tile) give the exact target
1691 reqs gives the requirement vector.
1692 The function returns TRUE only if all requirements are active.
1694 Make sure you give all aspects of the target when calling this function:
1695 for instance if you have TARGET_CITY pass the city's owner as the target
1696 player as well as the city itself as the target city.
1697 ****************************************************************************/
1698 bool are_reqs_active(const struct player *target_player,
1699 const struct city *target_city,
1700 const struct impr_type *target_building,
1701 const struct tile *target_tile,
1702 const struct unit_type *target_unittype,
1703 const struct output_type *target_output,
1704 const struct specialist *target_specialist,
1705 const struct requirement_vector *reqs,
1706 const enum req_problem_type prob_type)
1708 requirement_vector_iterate(reqs, preq) {
1709 if (!is_req_active(target_player, target_city, target_building,
1710 target_tile, target_unittype, target_output,
1711 target_specialist,
1712 preq, prob_type)) {
1713 return FALSE;
1715 } requirement_vector_iterate_end;
1716 return TRUE;
1719 /****************************************************************************
1720 Return TRUE if this is an "unchanging" requirement. This means that
1721 if a target can't meet the requirement now, it probably won't ever be able
1722 to do so later. This can be used to do requirement filtering when checking
1723 if a target may "eventually" become available.
1725 Note this isn't absolute. Returning TRUE here just means that the
1726 requirement probably can't be met. In some cases (particularly terrains)
1727 it may be wrong.
1728 *****************************************************************************/
1729 bool is_req_unchanging(const struct requirement *req)
1731 switch (req->source.kind) {
1732 case VUT_NATION:
1733 case VUT_NONE:
1734 case VUT_OTYPE:
1735 case VUT_SPECIALIST: /* Only so long as it's at local range only */
1736 case VUT_AI_LEVEL:
1737 case VUT_CITYTILE:
1738 return TRUE;
1739 case VUT_ADVANCE:
1740 case VUT_TECHFLAG:
1741 case VUT_GOVERNMENT:
1742 case VUT_IMPROVEMENT:
1743 case VUT_MINSIZE:
1744 case VUT_NATIONALITY:
1745 case VUT_UTYPE: /* Not sure about this one */
1746 case VUT_UTFLAG: /* Not sure about this one */
1747 case VUT_UCLASS: /* Not sure about this one */
1748 case VUT_UCFLAG: /* Not sure about this one */
1749 case VUT_ROAD:
1750 return FALSE;
1751 case VUT_SPECIAL:
1752 case VUT_TERRAIN:
1753 case VUT_RESOURCE:
1754 case VUT_TERRAINCLASS:
1755 case VUT_TERRFLAG:
1756 case VUT_TERRAINALTER:
1757 case VUT_BASE:
1758 /* Terrains, specials and bases aren't really unchanging; in fact they're
1759 * practically guaranteed to change. We return TRUE here for historical
1760 * reasons and so that the AI doesn't get confused (since the AI
1761 * doesn't know how to meet special and terrain requirements). */
1762 return TRUE;
1763 case VUT_MINYEAR:
1764 /* Once year is reached, it does not change again */
1765 return req->source.value.minyear > game.info.year;
1766 case VUT_COUNT:
1767 break;
1769 fc_assert_msg(FALSE, "Invalid source kind %d.", req->source.kind);
1770 return TRUE;
1773 /****************************************************************************
1774 Return TRUE iff the two sources are equivalent. Note this isn't the
1775 same as an == or memcmp check.
1776 *****************************************************************************/
1777 bool are_universals_equal(const struct universal *psource1,
1778 const struct universal *psource2)
1780 if (psource1->kind != psource2->kind) {
1781 return FALSE;
1783 switch (psource1->kind) {
1784 case VUT_NONE:
1785 return TRUE;
1786 case VUT_ADVANCE:
1787 return psource1->value.advance == psource2->value.advance;
1788 case VUT_TECHFLAG:
1789 return psource1->value.techflag == psource2->value.techflag;
1790 case VUT_GOVERNMENT:
1791 return psource1->value.govern == psource2->value.govern;
1792 case VUT_IMPROVEMENT:
1793 return psource1->value.building == psource2->value.building;
1794 case VUT_SPECIAL:
1795 return psource1->value.special == psource2->value.special;
1796 case VUT_TERRAIN:
1797 return psource1->value.terrain == psource2->value.terrain;
1798 case VUT_TERRFLAG:
1799 return psource1->value.terrainflag == psource2->value.terrainflag;
1800 case VUT_RESOURCE:
1801 return psource1->value.resource == psource2->value.resource;
1802 case VUT_NATION:
1803 return psource1->value.nation == psource2->value.nation;
1804 case VUT_NATIONALITY:
1805 return psource1->value.nationality == psource2->value.nationality;
1806 case VUT_UTYPE:
1807 return psource1->value.utype == psource2->value.utype;
1808 case VUT_UTFLAG:
1809 return psource1->value.unitflag == psource2->value.unitflag;
1810 case VUT_UCLASS:
1811 return psource1->value.uclass == psource2->value.uclass;
1812 case VUT_UCFLAG:
1813 return psource1->value.unitclassflag == psource2->value.unitclassflag;
1814 case VUT_OTYPE:
1815 return psource1->value.outputtype == psource2->value.outputtype;
1816 case VUT_SPECIALIST:
1817 return psource1->value.specialist == psource2->value.specialist;
1818 case VUT_MINSIZE:
1819 return psource1->value.minsize == psource2->value.minsize;
1820 case VUT_AI_LEVEL:
1821 return psource1->value.ai_level == psource2->value.ai_level;
1822 case VUT_TERRAINCLASS:
1823 return psource1->value.terrainclass == psource2->value.terrainclass;
1824 case VUT_BASE:
1825 return psource1->value.base == psource2->value.base;
1826 case VUT_ROAD:
1827 return psource1->value.road == psource2->value.road;
1828 case VUT_MINYEAR:
1829 return psource1->value.minyear == psource2->value.minyear;
1830 case VUT_TERRAINALTER:
1831 return psource1->value.terrainalter == psource2->value.terrainalter;
1832 case VUT_CITYTILE:
1833 return psource1->value.citytile == psource2->value.citytile;
1834 case VUT_COUNT:
1835 break;
1838 fc_assert_msg(FALSE, "Invalid source kind %d.", psource1->kind);
1839 return FALSE;
1842 /****************************************************************************
1843 Return the (untranslated) rule name of the universal.
1844 You don't have to free the return pointer.
1845 *****************************************************************************/
1846 const char *universal_rule_name(const struct universal *psource)
1848 static char buffer[10];
1850 switch (psource->kind) {
1851 case VUT_NONE:
1852 return "(none)";
1853 case VUT_CITYTILE:
1854 if (psource->value.citytile == CITYT_CENTER) {
1855 return "Center";
1856 } else {
1857 return "(none)";
1859 case VUT_MINYEAR:
1860 fc_snprintf(buffer, sizeof(buffer), "%d", psource->value.minyear);
1862 return buffer;
1863 case VUT_ADVANCE:
1864 return advance_rule_name(psource->value.advance);
1865 case VUT_TECHFLAG:
1866 return tech_flag_id_name(psource->value.techflag);
1867 case VUT_GOVERNMENT:
1868 return government_rule_name(psource->value.govern);
1869 case VUT_IMPROVEMENT:
1870 return improvement_rule_name(psource->value.building);
1871 case VUT_SPECIAL:
1872 return special_rule_name(psource->value.special);
1873 case VUT_TERRAIN:
1874 return terrain_rule_name(psource->value.terrain);
1875 case VUT_TERRFLAG:
1876 return terrain_flag_id_name(psource->value.terrainflag);
1877 case VUT_RESOURCE:
1878 return resource_rule_name(psource->value.resource);
1879 case VUT_NATION:
1880 return nation_rule_name(psource->value.nation);
1881 case VUT_NATIONALITY:
1882 return nation_rule_name(psource->value.nationality);
1883 case VUT_UTYPE:
1884 return utype_rule_name(psource->value.utype);
1885 case VUT_UTFLAG:
1886 return unit_type_flag_id_name(psource->value.unitflag);
1887 case VUT_UCLASS:
1888 return uclass_rule_name(psource->value.uclass);
1889 case VUT_UCFLAG:
1890 return unit_class_flag_id_name(psource->value.unitclassflag);
1891 case VUT_OTYPE:
1892 return get_output_name(psource->value.outputtype);
1893 case VUT_SPECIALIST:
1894 return specialist_rule_name(psource->value.specialist);
1895 case VUT_MINSIZE:
1896 fc_snprintf(buffer, sizeof(buffer), "%d", psource->value.minsize);
1898 return buffer;
1899 case VUT_AI_LEVEL:
1900 return ai_level_name(psource->value.ai_level);
1901 case VUT_TERRAINCLASS:
1902 return terrain_class_name(psource->value.terrainclass);
1903 case VUT_BASE:
1904 return base_rule_name(psource->value.base);
1905 case VUT_ROAD:
1906 return road_rule_name(psource->value.road);
1907 case VUT_TERRAINALTER:
1908 return terrain_alteration_name(psource->value.terrainalter);
1909 case VUT_COUNT:
1910 break;
1913 fc_assert_msg(FALSE, "Invalid source kind %d.", psource->kind);
1914 return NULL;
1917 /****************************************************************************
1918 Make user-friendly text for the source. The text is put into a user
1919 buffer which is also returned.
1920 *****************************************************************************/
1921 const char *universal_name_translation(const struct universal *psource,
1922 char *buf, size_t bufsz)
1924 buf[0] = '\0'; /* to be safe. */
1925 switch (psource->kind) {
1926 case VUT_NONE:
1927 /* TRANS: missing value */
1928 fc_strlcat(buf, _("(none)"), bufsz);
1929 return buf;
1930 case VUT_ADVANCE:
1931 fc_strlcat(buf, advance_name_translation(psource->value.advance), bufsz);
1932 return buf;
1933 case VUT_TECHFLAG:
1934 cat_snprintf(buf, bufsz, _("\"%s\" tech"),
1935 /* flag names are never translated */
1936 tech_flag_id_name(psource->value.techflag));
1937 return buf;
1938 case VUT_GOVERNMENT:
1939 fc_strlcat(buf, government_name_translation(psource->value.govern),
1940 bufsz);
1941 return buf;
1942 case VUT_IMPROVEMENT:
1943 fc_strlcat(buf, improvement_name_translation(psource->value.building),
1944 bufsz);
1945 return buf;
1946 case VUT_SPECIAL:
1947 fc_strlcat(buf, special_name_translation(psource->value.special), bufsz);
1948 return buf;
1949 case VUT_TERRAIN:
1950 fc_strlcat(buf, terrain_name_translation(psource->value.terrain), bufsz);
1951 return buf;
1952 case VUT_RESOURCE:
1953 fc_strlcat(buf, resource_name_translation(psource->value.resource), bufsz);
1954 return buf;
1955 case VUT_NATION:
1956 fc_strlcat(buf, nation_adjective_translation(psource->value.nation),
1957 bufsz);
1958 return buf;
1959 case VUT_NATIONALITY:
1960 fc_strlcat(buf, nation_adjective_translation(psource->value.nationality),
1961 bufsz);
1962 return buf;
1963 case VUT_UTYPE:
1964 fc_strlcat(buf, utype_name_translation(psource->value.utype), bufsz);
1965 return buf;
1966 case VUT_UTFLAG:
1967 cat_snprintf(buf, bufsz, _("\"%s\" units"),
1968 /* flag names are never translated */
1969 unit_type_flag_id_name(psource->value.unitflag));
1970 return buf;
1971 case VUT_UCLASS:
1972 cat_snprintf(buf, bufsz, _("%s units"),
1973 uclass_name_translation(psource->value.uclass));
1974 return buf;
1975 case VUT_UCFLAG:
1976 cat_snprintf(buf, bufsz, _("\"%s\" units"),
1977 /* flag names are never translated */
1978 unit_class_flag_id_name(psource->value.unitclassflag));
1979 return buf;
1980 case VUT_OTYPE:
1981 /* FIXME */
1982 fc_strlcat(buf, get_output_name(psource->value.outputtype), bufsz);
1983 return buf;
1984 case VUT_SPECIALIST:
1985 fc_strlcat(buf, specialist_plural_translation(psource->value.specialist),
1986 bufsz);
1987 return buf;
1988 case VUT_MINSIZE:
1989 cat_snprintf(buf, bufsz, _("Size %d"),
1990 psource->value.minsize);
1991 return buf;
1992 case VUT_AI_LEVEL:
1993 /* TRANS: "Hard AI" */
1994 cat_snprintf(buf, bufsz, _("%s AI"),
1995 ai_level_name(psource->value.ai_level)); /* FIXME */
1996 return buf;
1997 case VUT_TERRAINCLASS:
1998 /* TRANS: "Land terrain" */
1999 cat_snprintf(buf, bufsz, _("%s terrain"),
2000 terrain_class_name_translation(psource->value.terrainclass));
2001 return buf;
2002 case VUT_TERRFLAG:
2003 cat_snprintf(buf, bufsz, _("\"%s\" terrain"),
2004 /* flag names are never translated */
2005 terrain_flag_id_name(psource->value.terrainflag));
2006 return buf;
2007 case VUT_BASE:
2008 /* TRANS: "Fortress base" */
2009 cat_snprintf(buf, bufsz, _("%s base"),
2010 base_name_translation(psource->value.base));
2011 return buf;
2012 case VUT_ROAD:
2013 /* TRANS: Road type requirement: "Road" / "Railroad" / "Maglev" ... */
2014 cat_snprintf(buf, bufsz, Q_("?road:%s"),
2015 road_name_translation(psource->value.road));
2016 return buf;
2017 case VUT_MINYEAR:
2018 cat_snprintf(buf, bufsz, _("After %s"),
2019 textyear(psource->value.minyear));
2020 return buf;
2021 case VUT_TERRAINALTER:
2022 /* TRANS: "Irrigation possible" */
2023 cat_snprintf(buf, bufsz, _("%s possible"),
2024 terrain_alteration_name_translation(psource->value.terrainalter));
2025 return buf;
2026 case VUT_CITYTILE:
2027 fc_strlcat(buf, _("City center tile"), bufsz);
2028 return buf;
2029 case VUT_COUNT:
2030 break;
2033 fc_assert_msg(FALSE, "Invalid source kind %d.", psource->kind);
2034 return buf;
2037 /****************************************************************************
2038 Return untranslated name of the universal source name.
2039 *****************************************************************************/
2040 const char *universal_type_rule_name(const struct universal *psource)
2042 return universals_n_name(psource->kind);
2045 /**************************************************************************
2046 Return the number of shields it takes to build this universal.
2047 **************************************************************************/
2048 int universal_build_shield_cost(const struct universal *target)
2050 switch (target->kind) {
2051 case VUT_IMPROVEMENT:
2052 return impr_build_shield_cost(target->value.building);
2053 case VUT_UTYPE:
2054 return utype_build_shield_cost(target->value.utype);
2055 default:
2056 break;
2058 return FC_INFINITY;