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/* utility */
19#include "mem.h"
20
21/* common */
22#include "actres.h"
23#include "nation.h"
24#include "player.h"
25
26#include "oblig_reqs.h"
27
28
29/* Hard requirements relates to action result. */
32
33
34/**********************************************************************/
47{
48 struct ae_contra_or *out;
49 int i;
50 va_list args;
51
53 out = fc_malloc(sizeof(*out));
54 out->users = 0;
55 out->alternatives = alternatives;
56 out->alternative = fc_malloc(sizeof(out->alternative[0]) * alternatives);
57
59 for (i = 0; i < alternatives; i++) {
60 struct requirement contradiction = va_arg(args, struct requirement);
61 bool is_target = va_arg(args, int);
62
63 out->alternative[i].req = contradiction;
64 out->alternative[i].is_target = is_target;
65 }
66 va_end(args);
67
68 return out;
69}
70
71/**********************************************************************/
77{
78 contra->users--;
79
80 if (contra->users < 1) {
81 /* No users left. Delete. */
82 FC_FREE(contra->alternative);
84 }
85}
86
87/**********************************************************************/
97static void voblig_hard_req_reg_sub_res(struct ae_contra_or *contras,
98 const char *error_message,
99 va_list args)
100{
101 struct obligatory_req oreq;
103
104 /* A non null action message is used to indicate that an obligatory hard
105 * requirement is missing. */
107
108 /* Pack the obligatory hard requirement. */
109 oreq.contras = contras;
110 oreq.error_msg = error_message;
111
112 /* Add the obligatory hard requirement to each action sub result it
113 * applies to. */
114 while (ACT_SUB_RES_COUNT != (res = va_arg(args,
115 enum action_sub_result))) {
116 /* Any invalid action sub result should terminate the loop before this
117 * assertion. */
119 "Invalid action result %d", res);
120
121 /* Add to list for action result */
123
124 /* Register the new user. */
125 oreq.contras->users++;
126 }
127}
128
129/**********************************************************************/
141 const char *error_message,
142 ...)
143{
144 va_list args;
145
146 /* Add the obligatory hard requirement to each action result it applies
147 * to. */
148 va_start(args, error_message);
150 va_end(args);
151}
152
153/**********************************************************************/
163 const char *error_message,
164 va_list args)
165{
166 struct obligatory_req oreq;
167 enum action_result res;
168 int users = 0;
169
170 /* A non null action message is used to indicate that an obligatory hard
171 * requirement is missing. */
173
174 /* Pack the obligatory hard requirement. */
175 oreq.contras = contras;
176 oreq.error_msg = error_message;
177
178 /* Add the obligatory hard requirement to each action result it applies
179 * to. */
180 while (ACTRES_NONE != (res = va_arg(args, enum action_result))) {
181 /* Any invalid action result should terminate the loop before this
182 * assertion. */
184 "Invalid action result %d", res);
185
186 /* Add to list for action result */
188
189 /* Register the new user. */
190 users++;
191 }
192
193 fc_assert(users > 0);
194
195 oreq.contras->users += users;
196}
197
198/**********************************************************************/
208 const char *error_message,
209 ...)
210{
211 va_list args;
212
213 /* Add the obligatory hard requirement to each action result it applies
214 * to. */
215 va_start(args, error_message);
217 va_end(args);
218}
219
220/**********************************************************************/
228 bool is_target,
229 const char *error_message,
230 ...)
231{
232 struct ae_contra_or *contra;
233 va_list args;
234
235 /* Pack the obligatory hard requirement. */
237
238 /* Add the obligatory hard requirement to each action result it applies
239 * to. */
240 va_start(args, error_message);
242 va_end(args);
243}
244
245/**********************************************************************/
251{
252 /* Why this is a hard requirement: There is currently no point in
253 * allowing the listed actions against domestic targets.
254 * (Possible counter argument: crazy hack involving the Lua
255 * callback action_started_callback() to use an action to do
256 * something else. */
257 /* TODO: Unhardcode as a part of false flag operation support. */
260 FALSE,
261 N_("All action enablers for %s must require a "
262 "foreign target."),
275 /* The same for tile targeted actions that also can be done to unclaimed
276 * tiles. */
278 2,
281 FALSE,
283 FALSE, TRUE, TRUE,
285 TRUE),
286 /* TRANS: error message for ruledit */
287 N_("All action enablers for %s must require a "
288 "non domestic target."),
291 /* The same for tile extras targeted actions that also can be done to
292 * unowned extras. */
294 2,
297 FALSE,
299 FALSE, TRUE, TRUE,
301 TRUE),
302 /* TRANS: error message for ruledit */
303 N_("All action enablers for %s must require a "
304 "non domestic target."),
307
308 /* Why this is a hard requirement: There is currently no point in
309 * establishing an embassy when a real embassy already exists.
310 * (Possible exception: crazy hack using the Lua callback
311 * action_started_callback() to make establish embassy do something
312 * else even if the UI still call the action Establish Embassy) */
314 FALSE, TRUE, TRUE,
316 FALSE,
317 N_("All action enablers for %s must require the"
318 " absence of a real embassy."),
321
322 /* Why this is a hard requirement: There is currently no point in
323 * fortifying an already fortified unit. */
325 FALSE, TRUE, TRUE,
327 FALSE,
328 N_("All action enablers for %s must require that"
329 " the actor unit isn't already fortified."),
332
333 /* Why this is a hard requirement: Keep the old rules. Need to work
334 * out corner cases. */
337 FALSE,
338 N_("All action enablers for %s must require"
339 " a domestic target."),
341
342 /* Why this is a hard requirement: The code expects that only domestic and
343 * allied transports can be boarded. */
346 FALSE,
347 N_("All action enablers for %s must require"
348 " a domestic or allied target."),
354 FALSE, TRUE, TRUE, DS_WAR),
355 FALSE,
356 N_("All action enablers for %s must require"
357 " a domestic or allied target."),
364 FALSE,
365 N_("All action enablers for %s must require"
366 " a domestic or allied target."),
373 FALSE,
374 N_("All action enablers for %s must require"
375 " a domestic or allied target."),
382 FALSE,
383 N_("All action enablers for %s must require"
384 " a domestic or allied target."),
389
390 /* Why this is a hard requirement: Preserve semantics of the Settlers
391 * unit type flag. */
393 FALSE, FALSE, TRUE,
395 FALSE,
396 N_("All action enablers for %s must require"
397 " that the actor has"
398 " the Workers utype flag."),
407
408 /* Why this is a hard requirement: Preserve semantics of the rule that a
409 * *_time of 0 disables the action. */
411 FALSE, FALSE, FALSE,
413 TRUE,
414 N_("All action enablers for %s must require"
415 " that the target"
416 " tile's terrain's irrigation_time"
417 " is above 0. (See \"TerrainAlter\"'s"
418 " \"CanIrrigate\")"),
422 FALSE, FALSE, FALSE,
424 TRUE,
425 N_("All action enablers for %s must require"
426 " that the target"
427 " tile's terrain's mining_time"
428 " is above 0. (See \"TerrainAlter\"'s"
429 " \"CanMine\")"),
433 FALSE, FALSE, FALSE,
435 TRUE,
436 N_("All action enablers for %s must require"
437 " that the target"
438 " tile's terrain's road_time"
439 " is above 0. (See \"TerrainAlter\"'s"
440 " \"CanRoad\")"),
444 FALSE, FALSE, FALSE,
446 TRUE,
447 N_("All action enablers for %s must require"
448 " that the target"
449 " tile's terrain's base_time"
450 " is above 0. (See \"TerrainAlter\"'s"
451 " \"CanBase\")"),
454
455 /* Why this is a hard requirement: Preserve semantics of the NoCities
456 * terrain flag. */
458 FALSE, TRUE, TRUE,
460 TRUE,
461 N_("All action enablers for %s must require that"
462 " the target doesn't have"
463 " the NoCities terrain flag."),
466
467 /* It isn't possible to establish a trade route from a non existing
468 * city. The Freeciv code assumes this applies to Enter Marketplace
469 * too. */
471 FALSE, FALSE, TRUE,
473 FALSE,
474 N_("All action enablers for %s must require"
475 " that the actor has a home city."),
479
480 /* Why this is a hard requirement:
481 * - preserve the semantics of the NonMil unit type flag. */
483 3,
485 FALSE, FALSE, TRUE,
487 FALSE,
490 FALSE,
492 FALSE, TRUE, TRUE,
494 TRUE),
495 /* TRANS: error message for ruledit */
496 N_("All action enablers for %s must require"
497 " that the actor has the NonMil utype flag"
498 " or that the target tile is unclaimed"
499 " or that the diplomatic relation to"
500 " the target tile owner isn't peace."),
504
505 /* Why this is a hard requirement: Preserve semantics of NonMil
506 * flag. Need to replace other uses in game engine before this can
507 * be demoted to a regular unit flag. */
510 FALSE,
511 N_("All action enablers for %s must require"
512 " that the actor doesn't have"
513 " the NonMil utype flag."),
519 2,
522 FALSE,
524 FALSE, TRUE, TRUE,
526 TRUE),
527 /* TRANS: error message for ruledit */
528 N_("All action enablers for %s must require"
529 " no city at the target tile or"
530 " that the actor doesn't have"
531 " the NonMil utype flag."),
534
535 /* Why this is a hard requirement: Preserve semantics of
536 * CanOccupyCity unit class flag. */
538 FALSE, FALSE, TRUE,
540 FALSE,
541 N_("All action enablers for %s must require"
542 " that the actor has"
543 " the CanOccupyCity uclass flag."),
547 2,
549 FALSE, FALSE, TRUE,
551 FALSE,
553 FALSE, TRUE, TRUE,
555 TRUE),
556 /* TRANS: error message for ruledit */
557 N_("All action enablers for %s must require"
558 " no city at the target tile or"
559 " that the actor has"
560 " the CanOccupyCity uclass flag."),
563
564 /* Why this is a hard requirement: Consistency with ACTRES_ATTACK.
565 * Assumed by other locations in the Freeciv code. Examples:
566 * unit_move_to_tile_test(), unit_conquer_city() and do_paradrop(). */
569 FALSE,
570 N_("All action enablers for %s must require"
571 " that the actor is at war with the target."),
575 2,
578 FALSE,
580 FALSE, TRUE, TRUE,
582 TRUE),
583 /* TRANS: error message for ruledit */
584 N_("All action enablers for %s must require"
585 " no city at the target tile or"
586 " that the actor is at war with the target."),
589
590 /* Why this is a hard requirement: a unit must move into a city to
591 * conquer it, move into a transport to embark, move out of a transport
592 * to disembark from it, move into an extra to conquer it and move into a
593 * hut to enter/frighten it. */
595 FALSE, FALSE, TRUE, 1),
596 FALSE,
597 N_("All action enablers for %s must require"
598 " that the actor has a movement point left."),
607
608 /* Why this is a hard requirement: this eliminates the need to
609 * check if units transported by the actor unit can exist at the
610 * same tile as all the units in the occupied city.
611 *
612 * This makes an implicit rule explicit:
613 * 1. A unit must move into a city to conquer it.
614 * 2. It can't move into the city if the tile contains a non-allied
615 * unit (see unit_move_to_tile_test()).
616 * 3. A city could, at the time this rule was made explicit, only
617 * contain units allied to its owner.
618 * 3. A player could, at the time this rule was made explicit, not
619 * be allied to a player that is at war with another ally.
620 * 4. A player could, at the time this rule was made explicit, only
621 * conquer a city belonging to someone they were at war with.
622 * Conclusion: the conquered city had to be empty.
623 */
625 FALSE, FALSE, TRUE, 0),
626 TRUE,
627 N_("All action enablers for %s must require"
628 " that the target city is empty."),
631
632 /* Why this is a hard requirement: Assumed in the code. Corner case
633 * where diplomacy prevents a transported unit to go to the target
634 * tile. The paradrop code doesn't check if transported units can
635 * coexist with the target tile city and units. */
637 FALSE, TRUE, TRUE,
639 FALSE,
640 N_("All action enablers for %s must require"
641 " that the actor isn't transporting"
642 " another unit."),
647
648 /* Why this is a hard requirement: sanity. */
650 FALSE, FALSE, FALSE,
652 FALSE,
653 N_("All action enablers for %s must require"
654 " that the actor has a home city."),
656
657 /* Why this is a hard requirement: Assumed in the code.
658 * See hrm Bug #772516 - https://www.hostedredmine.com/issues/772516 */
660 FALSE, TRUE, TRUE,
662 TRUE,
663 N_("All action enablers for %s must require"
664 " that the target isn't transporting another"
665 " unit."),
667
668 /* Why this is a hard requirement: sanity. */
670 FALSE, FALSE, TRUE,
672 TRUE,
673 N_("All action enablers for %s must require"
674 " that the target is transporting a unit."),
677 FALSE, FALSE, TRUE,
679 FALSE,
680 N_("All action enablers for %s must require"
681 " that the actor is transported."),
686 FALSE, FALSE, TRUE,
688 FALSE,
689 N_("All action enablers for %s must require"
690 " that the actor is on a livable tile."),
692
693 /* Why this is a hard requirement: sanity. */
695 FALSE, FALSE, TRUE,
697 FALSE,
698 N_("All action enablers for %s must require"
699 " that the actor is transporting a unit."),
702 FALSE, FALSE, TRUE,
704 TRUE,
705 N_("All action enablers for %s must require"
706 " that the target is transported."),
709 FALSE, FALSE, TRUE,
711 TRUE,
712 N_("All action enablers for %s must require"
713 " that the target is on a livable tile."),
715
716 /* Why this is a hard requirement: Use ACTRES_TRANSPORT_DISEMBARK to
717 * disembark. Assumed by the Freeciv code. */
719 FALSE, TRUE, TRUE,
721 FALSE,
722 N_("All action enablers for %s must require"
723 " that the actor isn't transported."),
727
728 /* Why this is a hard requirement: assumed by the Freeciv code. */
730 FALSE, FALSE, TRUE,
732 FALSE,
733 N_("All action enablers for %s must require"
734 " that the actor unit is in a city."),
737
738 /* Why this is a hard requirement: Give meaning to the HutFrighten unit
739 * class flag. The point of it is to keep our options open for how both
740 * entering and frightening a hut at the same tile should be handled.
741 * See hrm Feature #920427 */
743 1,
745 FALSE, TRUE, FALSE,
747 FALSE),
748 N_("All action enablers for %s must require"
749 " that the actor unit doesn't have the"
750 " HutFrighten unit class flag."),
754 1,
756 FALSE, FALSE, FALSE,
758 FALSE),
759 N_("All action enablers for %s must require"
760 " that the actor unit has the HutFrighten"
761 " unit class flag."),
764}
765
766/**********************************************************************/
771{
772 /* Why this is a hard requirement: the "animal can't conquer a city"
773 * rule. Assumed in unit_can_take_over(). */
774 nations_iterate(pnation) {
775 if (nation_barbarian_type(pnation) == ANIMAL_BARBARIAN) {
777 FALSE, TRUE, TRUE,
778 nation_number(pnation)),
779 FALSE,
780 N_("All action enablers for %s must require"
781 " a non animal player actor."),
785 2,
787 FALSE, TRUE, TRUE,
788 nation_number(pnation)),
789 FALSE,
791 FALSE, TRUE, TRUE,
793 TRUE),
794 /* TRANS: error message for ruledit */
795 N_("All action enablers for %s must require"
796 " no city at the target tile or"
797 " a non animal player actor."),
800 }
802}
803
804/**********************************************************************/
808{
809 int i;
810
811 /* Obligatory hard requirements sorted by action result in memory. */
812 for (i = 0; i < ACTRES_NONE; i++) {
813 /* Prepare each action result's storage area. */
815 }
816
817 /* Obligatory hard requirements sorted by action sub result in memory. */
818 for (i = 0; i < ACT_SUB_RES_COUNT; i++) {
819 /* Prepare each action sub result's storage area. */
821 }
822}
823
824/**********************************************************************/
845
846/**********************************************************************/
856
857/**********************************************************************/
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:207
static void voblig_hard_req_reg(struct ae_contra_or *contras, const char *error_message, va_list args)
Definition oblig_reqs.c:162
static struct obligatory_req_vector oblig_hard_reqs_r[ACTRES_NONE]
Definition oblig_reqs.c:30
void oblig_hard_reqs_init(void)
Definition oblig_reqs.c:807
static struct ae_contra_or * req_contradiction_or(int alternatives,...)
Definition oblig_reqs.c:46
void oblig_hard_reqs_free(void)
Definition oblig_reqs.c:827
static void ae_contra_close(struct ae_contra_or *contra)
Definition oblig_reqs.c:76
static struct obligatory_req_vector oblig_hard_reqs_sr[ACT_SUB_RES_COUNT]
Definition oblig_reqs.c:31
static void oblig_hard_req_reg_sub_res(struct ae_contra_or *contras, const char *error_message,...)
Definition oblig_reqs.c:140
static void voblig_hard_req_reg_sub_res(struct ae_contra_or *contras, const char *error_message, va_list args)
Definition oblig_reqs.c:97
void hard_code_oblig_hard_reqs_ruleset(void)
Definition oblig_reqs.c:770
void hard_code_oblig_hard_reqs(void)
Definition oblig_reqs.c:250
struct obligatory_req_vector * oblig_hard_reqs_get(enum action_result res)
Definition oblig_reqs.c:852
struct obligatory_req_vector * oblig_hard_reqs_get_sub(enum action_sub_result res)
Definition oblig_reqs.c:863
static void oblig_hard_req_register(struct requirement contradiction, bool is_target, const char *error_message,...)
Definition oblig_reqs.c:227
#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