Freeciv-3.3
Loading...
Searching...
No Matches
oblig_reqs.c
Go to the documentation of this file.
1/****************************************************************************
2 Freeciv - Copyright (C) 2004 - The Freeciv Team
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.
7
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
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdarg.h>
19
20/* utility */
21#include "mem.h"
22
23/* common */
24#include "actres.h"
25#include "nation.h"
26#include "player.h"
27
28#include "oblig_reqs.h"
29
30
31/* Hard requirements relates to action result. */
34
35
36/**********************************************************************/
49{
50 struct ae_contra_or *out;
51 int i;
52 va_list args;
53
55 out = fc_malloc(sizeof(*out));
56 out->users = 0;
57 out->alternatives = alternatives;
58 out->alternative = fc_malloc(sizeof(out->alternative[0]) * alternatives);
59
61 for (i = 0; i < alternatives; i++) {
62 struct requirement contradiction = va_arg(args, struct requirement);
63 bool is_target = va_arg(args, int);
64
65 out->alternative[i].req = contradiction;
66 out->alternative[i].is_target = is_target;
67 }
68 va_end(args);
69
70 return out;
71}
72
73/**********************************************************************/
79{
80 contra->users--;
81
82 if (contra->users < 1) {
83 /* No users left. Delete. */
84 FC_FREE(contra->alternative);
86 }
87}
88
89/**********************************************************************/
99static void voblig_hard_req_reg_sub_res(struct ae_contra_or *contras,
100 const char *error_message,
101 va_list args)
102{
103 struct obligatory_req oreq;
105
106 /* A non null action message is used to indicate that an obligatory hard
107 * requirement is missing. */
109
110 /* Pack the obligatory hard requirement. */
111 oreq.contras = contras;
112 oreq.error_msg = error_message;
113
114 /* Add the obligatory hard requirement to each action sub result it
115 * applies to. */
116 while (ACT_SUB_RES_COUNT != (res = va_arg(args,
117 enum action_sub_result))) {
118 /* Any invalid action sub result should terminate the loop before this
119 * assertion. */
121 "Invalid action result %d", res);
122
123 /* Add to list for action result */
125
126 /* Register the new user. */
127 oreq.contras->users++;
128 }
129}
130
131/**********************************************************************/
143 const char *error_message,
144 ...)
145{
146 va_list args;
147
148 /* Add the obligatory hard requirement to each action result it applies
149 * to. */
150 va_start(args, error_message);
152 va_end(args);
153}
154
155/**********************************************************************/
165 const char *error_message,
166 va_list args)
167{
168 struct obligatory_req oreq;
169 enum action_result res;
170 int users = 0;
171
172 /* A non null action message is used to indicate that an obligatory hard
173 * requirement is missing. */
175
176 /* Pack the obligatory hard requirement. */
177 oreq.contras = contras;
178 oreq.error_msg = error_message;
179
180 /* Add the obligatory hard requirement to each action result it applies
181 * to. */
182 while (ACTRES_NONE != (res = va_arg(args, enum action_result))) {
183 /* Any invalid action result should terminate the loop before this
184 * assertion. */
186 "Invalid action result %d", res);
187
188 /* Add to list for action result */
190
191 /* Register the new user. */
192 users++;
193 }
194
195 fc_assert(users > 0);
196
197 oreq.contras->users += users;
198}
199
200/**********************************************************************/
210 const char *error_message,
211 ...)
212{
213 va_list args;
214
215 /* Add the obligatory hard requirement to each action result it applies
216 * to. */
217 va_start(args, error_message);
219 va_end(args);
220}
221
222/**********************************************************************/
230 bool is_target,
231 const char *error_message,
232 ...)
233{
234 struct ae_contra_or *contra;
235 va_list args;
236
237 /* Pack the obligatory hard requirement. */
239
240 /* Add the obligatory hard requirement to each action result it applies
241 * to. */
242 va_start(args, error_message);
244 va_end(args);
245}
246
247/**********************************************************************/
253{
254 /* Why this is a hard requirement: There is currently no point in
255 * allowing the listed actions against domestic targets.
256 * (Possible counter argument: crazy hack involving the Lua
257 * callback action_started_callback() to use an action to do
258 * something else. */
259 /* TODO: Unhardcode as a part of false flag operation support. */
262 FALSE,
263 N_("All action enablers for %s must require a "
264 "foreign target."),
277 /* The same for tile targeted actions that also can be done to unclaimed
278 * tiles. */
280 2,
283 FALSE,
285 FALSE, TRUE, TRUE,
287 TRUE),
288 /* TRANS: error message for ruledit */
289 N_("All action enablers for %s must require a "
290 "non domestic target."),
293 /* The same for tile extras targeted actions that also can be done to
294 * unowned extras. */
296 2,
299 FALSE,
301 FALSE, TRUE, TRUE,
303 TRUE),
304 /* TRANS: error message for ruledit */
305 N_("All action enablers for %s must require a "
306 "non domestic target."),
309
310 /* Why this is a hard requirement: There is currently no point in
311 * establishing an embassy when a real embassy already exists.
312 * (Possible exception: crazy hack using the Lua callback
313 * action_started_callback() to make establish embassy do something
314 * else even if the UI still call the action Establish Embassy) */
316 FALSE, TRUE, TRUE,
318 FALSE,
319 N_("All action enablers for %s must require the"
320 " absence of a real embassy."),
323
324 /* Why this is a hard requirement: There is currently no point in
325 * fortifying an already fortified unit. */
327 FALSE, TRUE, TRUE,
329 FALSE,
330 N_("All action enablers for %s must require that"
331 " the actor unit isn't already fortified."),
334
335 /* Why this is a hard requirement: Keep the old rules. Need to work
336 * out corner cases. */
339 FALSE,
340 N_("All action enablers for %s must require"
341 " a domestic target."),
343
344 /* Why this is a hard requirement: The code expects that only domestic and
345 * allied transports can be boarded. */
348 FALSE,
349 N_("All action enablers for %s must require"
350 " a domestic or allied target."),
356 FALSE, TRUE, TRUE, DS_WAR),
357 FALSE,
358 N_("All action enablers for %s must require"
359 " a domestic or allied target."),
366 FALSE,
367 N_("All action enablers for %s must require"
368 " a domestic or allied target."),
375 FALSE,
376 N_("All action enablers for %s must require"
377 " a domestic or allied target."),
384 FALSE,
385 N_("All action enablers for %s must require"
386 " a domestic or allied target."),
391
392 /* Why this is a hard requirement: Preserve semantics of the Settlers
393 * unit type flag. */
395 FALSE, FALSE, TRUE,
397 FALSE,
398 N_("All action enablers for %s must require"
399 " that the actor has"
400 " the Workers utype flag."),
409
410 /* Why this is a hard requirement: Preserve semantics of the rule that a
411 * *_time of 0 disables the action. */
413 FALSE, FALSE, FALSE,
415 TRUE,
416 N_("All action enablers for %s must require"
417 " that the target"
418 " tile's terrain's irrigation_time"
419 " is above 0. (See \"TerrainAlter\"'s"
420 " \"CanIrrigate\")"),
424 FALSE, FALSE, FALSE,
426 TRUE,
427 N_("All action enablers for %s must require"
428 " that the target"
429 " tile's terrain's mining_time"
430 " is above 0. (See \"TerrainAlter\"'s"
431 " \"CanMine\")"),
435 FALSE, FALSE, FALSE,
437 TRUE,
438 N_("All action enablers for %s must require"
439 " that the target"
440 " tile's terrain's road_time"
441 " is above 0. (See \"TerrainAlter\"'s"
442 " \"CanRoad\")"),
446 FALSE, FALSE, FALSE,
448 TRUE,
449 N_("All action enablers for %s must require"
450 " that the target"
451 " tile's terrain's base_time"
452 " is above 0. (See \"TerrainAlter\"'s"
453 " \"CanBase\")"),
456
457 /* Why this is a hard requirement: Preserve semantics of the NoCities
458 * terrain flag. */
460 FALSE, TRUE, TRUE,
462 TRUE,
463 N_("All action enablers for %s must require that"
464 " the target doesn't have"
465 " the NoCities terrain flag."),
468
469 /* It isn't possible to establish a trade route from a non existing
470 * city. The Freeciv code assumes this applies to Enter Marketplace
471 * too. */
473 FALSE, FALSE, TRUE,
475 FALSE,
476 N_("All action enablers for %s must require"
477 " that the actor has a home city."),
481
482 /* Why this is a hard requirement:
483 * - preserve the semantics of the NonMil unit type flag. */
485 3,
487 FALSE, FALSE, TRUE,
489 FALSE,
492 FALSE,
494 FALSE, TRUE, TRUE,
496 TRUE),
497 /* TRANS: error message for ruledit */
498 N_("All action enablers for %s must require"
499 " that the actor has the NonMil utype flag"
500 " or that the target tile is unclaimed"
501 " or that the diplomatic relation to"
502 " the target tile owner isn't peace."),
506
507 /* Why this is a hard requirement: Preserve semantics of NonMil
508 * flag. Need to replace other uses in game engine before this can
509 * be demoted to a regular unit flag. */
512 FALSE,
513 N_("All action enablers for %s must require"
514 " that the actor doesn't have"
515 " the NonMil utype flag."),
521 2,
524 FALSE,
526 FALSE, TRUE, TRUE,
528 TRUE),
529 /* TRANS: error message for ruledit */
530 N_("All action enablers for %s must require"
531 " no city at the target tile or"
532 " that the actor doesn't have"
533 " the NonMil utype flag."),
536
537 /* Why this is a hard requirement: Preserve semantics of
538 * CanOccupyCity unit class flag. */
540 FALSE, FALSE, TRUE,
542 FALSE,
543 N_("All action enablers for %s must require"
544 " that the actor has"
545 " the CanOccupyCity uclass flag."),
549 2,
551 FALSE, FALSE, TRUE,
553 FALSE,
555 FALSE, TRUE, TRUE,
557 TRUE),
558 /* TRANS: error message for ruledit */
559 N_("All action enablers for %s must require"
560 " no city at the target tile or"
561 " that the actor has"
562 " the CanOccupyCity uclass flag."),
565
566 /* Why this is a hard requirement: Consistency with ACTRES_ATTACK.
567 * Assumed by other locations in the Freeciv code. Examples:
568 * unit_move_to_tile_test(), unit_conquer_city() and do_paradrop(). */
571 FALSE,
572 N_("All action enablers for %s must require"
573 " that the actor is at war with the target."),
577 2,
580 FALSE,
582 FALSE, TRUE, TRUE,
584 TRUE),
585 /* TRANS: error message for ruledit */
586 N_("All action enablers for %s must require"
587 " no city at the target tile or"
588 " that the actor is at war with the target."),
591
592 /* Why this is a hard requirement: a unit must move into a city to
593 * conquer it, move into a transport to embark, move out of a transport
594 * to disembark from it, move into an extra to conquer it and move into a
595 * hut to enter/frighten it. */
597 FALSE, FALSE, TRUE, 1),
598 FALSE,
599 N_("All action enablers for %s must require"
600 " that the actor has a movement point left."),
609
610 /* Why this is a hard requirement: this eliminates the need to
611 * check if units transported by the actor unit can exist at the
612 * same tile as all the units in the occupied city.
613 *
614 * This makes an implicit rule explicit:
615 * 1. A unit must move into a city to conquer it.
616 * 2. It can't move into the city if the tile contains a non-allied
617 * unit (see unit_move_to_tile_test()).
618 * 3. A city could, at the time this rule was made explicit, only
619 * contain units allied to its owner.
620 * 3. A player could, at the time this rule was made explicit, not
621 * be allied to a player that is at war with another ally.
622 * 4. A player could, at the time this rule was made explicit, only
623 * conquer a city belonging to someone they were at war with.
624 * Conclusion: the conquered city had to be empty.
625 */
627 FALSE, FALSE, TRUE, 0),
628 TRUE,
629 N_("All action enablers for %s must require"
630 " that the target city is empty."),
633
634 /* Why this is a hard requirement: Assumed in the code. Corner case
635 * where diplomacy prevents a transported unit to go to the target
636 * tile. The paradrop code doesn't check if transported units can
637 * coexist with the target tile city and units. */
639 FALSE, TRUE, TRUE,
641 FALSE,
642 N_("All action enablers for %s must require"
643 " that the actor isn't transporting"
644 " another unit."),
649
650 /* Why this is a hard requirement: sanity. */
652 FALSE, FALSE, FALSE,
654 FALSE,
655 N_("All action enablers for %s must require"
656 " that the actor has a home city."),
658
659 /* Why this is a hard requirement: Assumed in the code.
660 * See hrm Bug #772516 - https://www.hostedredmine.com/issues/772516 */
662 FALSE, TRUE, TRUE,
664 TRUE,
665 N_("All action enablers for %s must require"
666 " that the target isn't transporting another"
667 " unit."),
669
670 /* Why this is a hard requirement: sanity. */
672 FALSE, FALSE, TRUE,
674 TRUE,
675 N_("All action enablers for %s must require"
676 " that the target is transporting a unit."),
679 FALSE, FALSE, TRUE,
681 FALSE,
682 N_("All action enablers for %s must require"
683 " that the actor is transported."),
688 FALSE, FALSE, TRUE,
690 FALSE,
691 N_("All action enablers for %s must require"
692 " that the actor is on a livable tile."),
694
695 /* Why this is a hard requirement: sanity. */
697 FALSE, FALSE, TRUE,
699 FALSE,
700 N_("All action enablers for %s must require"
701 " that the actor is transporting a unit."),
704 FALSE, FALSE, TRUE,
706 TRUE,
707 N_("All action enablers for %s must require"
708 " that the target is transported."),
711 FALSE, FALSE, TRUE,
713 TRUE,
714 N_("All action enablers for %s must require"
715 " that the target is on a livable tile."),
717
718 /* Why this is a hard requirement: Use ACTRES_TRANSPORT_DISEMBARK to
719 * disembark. Assumed by the Freeciv code. */
721 FALSE, TRUE, TRUE,
723 FALSE,
724 N_("All action enablers for %s must require"
725 " that the actor isn't transported."),
729
730 /* Why this is a hard requirement: assumed by the Freeciv code. */
732 FALSE, FALSE, TRUE,
734 FALSE,
735 N_("All action enablers for %s must require"
736 " that the actor unit is in a city."),
739
740 /* Why this is a hard requirement: Give meaning to the HutFrighten unit
741 * class flag. The point of it is to keep our options open for how both
742 * entering and frightening a hut at the same tile should be handled.
743 * See hrm Feature #920427 */
745 1,
747 FALSE, TRUE, FALSE,
749 FALSE),
750 N_("All action enablers for %s must require"
751 " that the actor unit doesn't have the"
752 " HutFrighten unit class flag."),
756 1,
758 FALSE, FALSE, FALSE,
760 FALSE),
761 N_("All action enablers for %s must require"
762 " that the actor unit has the HutFrighten"
763 " unit class flag."),
766}
767
768/**********************************************************************/
773{
774 /* Why this is a hard requirement: the "animal can't conquer a city"
775 * rule. Assumed in unit_can_take_over(). */
776 nations_iterate(pnation) {
777 if (nation_barbarian_type(pnation) == ANIMAL_BARBARIAN) {
779 FALSE, TRUE, TRUE,
780 nation_number(pnation)),
781 FALSE,
782 N_("All action enablers for %s must require"
783 " a non animal player actor."),
787 2,
789 FALSE, TRUE, TRUE,
790 nation_number(pnation)),
791 FALSE,
793 FALSE, TRUE, TRUE,
795 TRUE),
796 /* TRANS: error message for ruledit */
797 N_("All action enablers for %s must require"
798 " no city at the target tile or"
799 " a non animal player actor."),
802 }
804}
805
806/**********************************************************************/
810{
811 int i;
812
813 /* Obligatory hard requirements sorted by action result in memory. */
814 for (i = 0; i < ACTRES_NONE; i++) {
815 /* Prepare each action result's storage area. */
817 }
818
819 /* Obligatory hard requirements sorted by action sub result in memory. */
820 for (i = 0; i < ACT_SUB_RES_COUNT; i++) {
821 /* Prepare each action sub result's storage area. */
823 }
824}
825
826/**********************************************************************/
847
848/**********************************************************************/
858
859/**********************************************************************/
char * incite_cost
Definition comments.c:76
#define ACTRES_NONE
Definition fc_types.h:186
#define N_(String)
Definition fcintl.h:69
#define fc_assert_ret(condition)
Definition log.h:192
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_msg(condition, message,...)
Definition log.h:206
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_malloc(sz)
Definition mem.h:34
Nation_type_id nation_number(const struct nation_type *pnation)
Definition nation.c:486
enum barbarian_type nation_barbarian_type(const struct nation_type *nation)
Definition nation.c:211
#define nations_iterate_end
Definition nation.h:336
#define nations_iterate(NAME_pnation)
Definition nation.h:333
static void oblig_hard_req_reg(struct ae_contra_or *contras, const char *error_message,...)
Definition oblig_reqs.c:209
static void voblig_hard_req_reg(struct ae_contra_or *contras, const char *error_message, va_list args)
Definition oblig_reqs.c:164
static struct obligatory_req_vector oblig_hard_reqs_r[ACTRES_NONE]
Definition oblig_reqs.c:32
void oblig_hard_reqs_init(void)
Definition oblig_reqs.c:809
static struct ae_contra_or * req_contradiction_or(int alternatives,...)
Definition oblig_reqs.c:48
void oblig_hard_reqs_free(void)
Definition oblig_reqs.c:829
static void ae_contra_close(struct ae_contra_or *contra)
Definition oblig_reqs.c:78
static struct obligatory_req_vector oblig_hard_reqs_sr[ACT_SUB_RES_COUNT]
Definition oblig_reqs.c:33
static void oblig_hard_req_reg_sub_res(struct ae_contra_or *contras, const char *error_message,...)
Definition oblig_reqs.c:142
static void voblig_hard_req_reg_sub_res(struct ae_contra_or *contras, const char *error_message, va_list args)
Definition oblig_reqs.c:99
void hard_code_oblig_hard_reqs_ruleset(void)
Definition oblig_reqs.c:772
void hard_code_oblig_hard_reqs(void)
Definition oblig_reqs.c:252
struct obligatory_req_vector * oblig_hard_reqs_get(enum action_result res)
Definition oblig_reqs.c:854
struct obligatory_req_vector * oblig_hard_reqs_get_sub(enum action_sub_result res)
Definition oblig_reqs.c:865
static void oblig_hard_req_register(struct requirement contradiction, bool is_target, const char *error_message,...)
Definition oblig_reqs.c:229
#define obligatory_req_vector_iterate_end
Definition oblig_reqs.h:48
#define obligatory_req_vector_iterate(obreq_vec, pobreq)
Definition oblig_reqs.h:46
struct requirement req_from_values(int type, int range, bool survives, bool present, bool quiet, int value)
struct ae_contra_or * contras
Definition oblig_reqs.h:36
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47