Freeciv-3.4
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
54 fc_assert_ret_val(alternatives > 0, nullptr);
55
56 out = fc_malloc(sizeof(*out));
57 out->users = 0;
58 out->alternatives = alternatives;
59 out->alternative = fc_malloc(sizeof(out->alternative[0]) * alternatives);
60
62 for (i = 0; i < alternatives; i++) {
63 struct requirement contradiction = va_arg(args, struct requirement);
64 bool is_target = va_arg(args, int);
65
66 out->alternative[i].req = contradiction;
67 out->alternative[i].is_target = is_target;
68 }
69 va_end(args);
70
71 return out;
72}
73
74/**********************************************************************/
80{
81 contra->users--;
82
83 if (contra->users < 1) {
84 /* No users left. Delete. */
85 FC_FREE(contra->alternative);
87 }
88}
89
90/**********************************************************************/
100static void voblig_hard_req_reg_sub_res(struct ae_contra_or *contras,
101 const char *error_message,
102 va_list args)
103{
104 struct obligatory_req oreq;
106
107 /* A non null action message is used to indicate that an obligatory hard
108 * requirement is missing. */
110
111 /* Pack the obligatory hard requirement. */
112 oreq.contras = contras;
113 oreq.error_msg = error_message;
114
115 /* Add the obligatory hard requirement to each action sub result it
116 * applies to. */
117 while (ACT_SUB_RES_COUNT != (res = va_arg(args,
118 enum action_sub_result))) {
119 /* Any invalid action sub result should terminate the loop before this
120 * assertion. */
122 "Invalid action result %d", res);
123
124 /* Add to list for action result */
126
127 /* Register the new user. */
128 oreq.contras->users++;
129 }
130}
131
132/**********************************************************************/
144 const char *error_message,
145 ...)
146{
147 va_list args;
148
149 /* Add the obligatory hard requirement to each action result it applies
150 * to. */
151 va_start(args, error_message);
153 va_end(args);
154}
155
156/**********************************************************************/
166 const char *error_message,
167 va_list args)
168{
169 struct obligatory_req oreq;
170 enum action_result res;
171 int users = 0;
172
173 /* A non null action message is used to indicate that an obligatory hard
174 * requirement is missing. */
176
177 /* Pack the obligatory hard requirement. */
178 oreq.contras = contras;
179 oreq.error_msg = error_message;
180
181 /* Add the obligatory hard requirement to each action result it applies
182 * to. */
183 while (ACTRES_NONE != (res = va_arg(args, enum action_result))) {
184 /* Any invalid action result should terminate the loop before this
185 * assertion. */
187 "Invalid action result %d", res);
188
189 /* Add to list for action result */
191
192 /* Register the new user. */
193 users++;
194 }
195
196 fc_assert(users > 0);
197
198 oreq.contras->users += users;
199}
200
201/**********************************************************************/
211 const char *error_message,
212 ...)
213{
214 va_list args;
215
216 /* Add the obligatory hard requirement to each action result it applies
217 * to. */
218 va_start(args, error_message);
220 va_end(args);
221}
222
223/**********************************************************************/
231 bool is_target,
232 const char *error_message,
233 ...)
234{
235 struct ae_contra_or *contra;
236 va_list args;
237
238 /* Pack the obligatory hard requirement. */
240
241 /* Add the obligatory hard requirement to each action result it applies
242 * to. */
243 va_start(args, error_message);
245 va_end(args);
246}
247
248/**********************************************************************/
254{
255 /* Why this is a hard requirement: There is currently no point in
256 * allowing the listed actions against domestic targets.
257 * (Possible counter argument: crazy hack involving the Lua
258 * callback action_started_callback() to use an action to do
259 * something else. */
260 /* TODO: Unhardcode as a part of false flag operation support. */
263 FALSE,
264 N_("All action enablers for %s must require a "
265 "foreign target."),
278 /* The same for tile targeted actions that also can be done to unclaimed
279 * tiles. */
281 2,
284 FALSE,
286 FALSE, TRUE, TRUE,
288 TRUE),
289 /* TRANS: error message for ruledit */
290 N_("All action enablers for %s must require a "
291 "non domestic target."),
294 /* The same for tile extras targeted actions that also can be done to
295 * unowned extras. */
297 2,
300 FALSE,
302 FALSE, TRUE, TRUE,
304 TRUE),
305 /* TRANS: error message for ruledit */
306 N_("All action enablers for %s must require a "
307 "non domestic target."),
310
311 /* Why this is a hard requirement: There is currently no point in
312 * establishing an embassy when a real embassy already exists.
313 * (Possible exception: crazy hack using the Lua callback
314 * action_started_callback() to make establish embassy do something
315 * else even if the UI still call the action Establish Embassy) */
317 FALSE, TRUE, TRUE,
319 FALSE,
320 N_("All action enablers for %s must require the"
321 " absence of a real embassy."),
324
325 /* Why this is a hard requirement: There is currently no point in
326 * fortifying an already fortified unit. */
328 FALSE, TRUE, TRUE,
330 FALSE,
331 N_("All action enablers for %s must require that"
332 " the actor unit isn't already fortified."),
335
336 /* Why this is a hard requirement: Keep the old rules. Need to work
337 * out corner cases. */
340 FALSE,
341 N_("All action enablers for %s must require"
342 " a domestic target."),
344
345 /* Why this is a hard requirement: The code expects that only domestic and
346 * allied transports can be boarded. */
349 FALSE,
350 N_("All action enablers for %s must require"
351 " a domestic or allied target."),
357 FALSE, TRUE, TRUE, DS_WAR),
358 FALSE,
359 N_("All action enablers for %s must require"
360 " a domestic or allied target."),
367 FALSE,
368 N_("All action enablers for %s must require"
369 " a domestic or allied target."),
376 FALSE,
377 N_("All action enablers for %s must require"
378 " a domestic or allied target."),
385 FALSE,
386 N_("All action enablers for %s must require"
387 " a domestic or allied target."),
392
393 /* Why this is a hard requirement: Preserve semantics of the Settlers
394 * unit type flag. */
396 FALSE, FALSE, TRUE,
398 FALSE,
399 N_("All action enablers for %s must require"
400 " that the actor has"
401 " the Workers utype flag."),
410
411 /* Why this is a hard requirement: Preserve semantics of the rule that a
412 * *_time of 0 disables the action. */
414 FALSE, FALSE, FALSE,
416 TRUE,
417 N_("All action enablers for %s must require"
418 " that the target"
419 " tile's terrain's irrigation_time"
420 " is above 0. (See \"TerrainAlter\"'s"
421 " \"CanIrrigate\")"),
425 FALSE, FALSE, FALSE,
427 TRUE,
428 N_("All action enablers for %s must require"
429 " that the target"
430 " tile's terrain's mining_time"
431 " is above 0. (See \"TerrainAlter\"'s"
432 " \"CanMine\")"),
436 FALSE, FALSE, FALSE,
438 TRUE,
439 N_("All action enablers for %s must require"
440 " that the target"
441 " tile's terrain's road_time"
442 " is above 0. (See \"TerrainAlter\"'s"
443 " \"CanRoad\")"),
447 FALSE, FALSE, FALSE,
449 TRUE,
450 N_("All action enablers for %s must require"
451 " that the target"
452 " tile's terrain's base_time"
453 " is above 0. (See \"TerrainAlter\"'s"
454 " \"CanBase\")"),
457
458 /* Why this is a hard requirement: Preserve semantics of the NoCities
459 * terrain flag. */
461 FALSE, TRUE, TRUE,
463 TRUE,
464 N_("All action enablers for %s must require that"
465 " the target doesn't have"
466 " the NoCities terrain flag."),
469
470 /* It isn't possible to establish a trade route from a non existing
471 * city. The Freeciv code assumes this applies to Enter Marketplace
472 * too. */
474 FALSE, FALSE, TRUE,
476 FALSE,
477 N_("All action enablers for %s must require"
478 " that the actor has a home city."),
482
483 /* Why this is a hard requirement:
484 * - preserve the semantics of the NonMil unit type flag. */
486 3,
488 FALSE, FALSE, TRUE,
490 FALSE,
493 FALSE,
495 FALSE, TRUE, TRUE,
497 TRUE),
498 /* TRANS: error message for ruledit */
499 N_("All action enablers for %s must require"
500 " that the actor has the NonMil utype flag"
501 " or that the target tile is unclaimed"
502 " or that the diplomatic relation to"
503 " the target tile owner isn't peace."),
507
508 /* Why this is a hard requirement: Preserve semantics of NonMil
509 * flag. Need to replace other uses in game engine before this can
510 * be demoted to a regular unit flag. */
513 FALSE,
514 N_("All action enablers for %s must require"
515 " that the actor doesn't have"
516 " the NonMil utype flag."),
522 2,
525 FALSE,
527 FALSE, TRUE, TRUE,
529 TRUE),
530 /* TRANS: error message for ruledit */
531 N_("All action enablers for %s must require"
532 " no city at the target tile or"
533 " that the actor doesn't have"
534 " the NonMil utype flag."),
537
538 /* Why this is a hard requirement: Preserve semantics of
539 * CanOccupyCity unit class flag. */
541 FALSE, FALSE, TRUE,
543 FALSE,
544 N_("All action enablers for %s must require"
545 " that the actor has"
546 " the CanOccupyCity uclass flag."),
550 2,
552 FALSE, FALSE, TRUE,
554 FALSE,
556 FALSE, TRUE, TRUE,
558 TRUE),
559 /* TRANS: error message for ruledit */
560 N_("All action enablers for %s must require"
561 " no city at the target tile or"
562 " that the actor has"
563 " the CanOccupyCity uclass flag."),
566
567 /* Why this is a hard requirement: Consistency with ACTRES_ATTACK.
568 * Assumed by other locations in the Freeciv code. Examples:
569 * unit_move_to_tile_test(), unit_conquer_city() and do_paradrop(). */
572 FALSE,
573 N_("All action enablers for %s must require"
574 " that the actor is at war with the target."),
578 2,
581 FALSE,
583 FALSE, TRUE, TRUE,
585 TRUE),
586 /* TRANS: error message for ruledit */
587 N_("All action enablers for %s must require"
588 " no city at the target tile or"
589 " that the actor is at war with the target."),
592
593 /* Why this is a hard requirement: a unit must move into a city to
594 * conquer it, move into a transport to embark, move out of a transport
595 * to disembark from it, move into an extra to conquer it and move into a
596 * hut to enter/frighten it. */
598 FALSE, FALSE, TRUE, 1),
599 FALSE,
600 N_("All action enablers for %s must require"
601 " that the actor has a movement point left."),
610
611 /* Why this is a hard requirement: this eliminates the need to
612 * check if units transported by the actor unit can exist at the
613 * same tile as all the units in the occupied city.
614 *
615 * This makes an implicit rule explicit:
616 * 1. A unit must move into a city to conquer it.
617 * 2. It can't move into the city if the tile contains a non-allied
618 * unit (see unit_move_to_tile_test()).
619 * 3. A city could, at the time this rule was made explicit, only
620 * contain units allied to its owner.
621 * 3. A player could, at the time this rule was made explicit, not
622 * be allied to a player that is at war with another ally.
623 * 4. A player could, at the time this rule was made explicit, only
624 * conquer a city belonging to someone they were at war with.
625 * Conclusion: the conquered city had to be empty.
626 */
628 FALSE, FALSE, TRUE, 0),
629 TRUE,
630 N_("All action enablers for %s must require"
631 " that the target city is empty."),
634
635 /* Why this is a hard requirement: Assumed in the code. Corner case
636 * where diplomacy prevents a transported unit to go to the target
637 * tile. The paradrop code doesn't check if transported units can
638 * coexist with the target tile city and units. */
640 FALSE, TRUE, TRUE,
642 FALSE,
643 N_("All action enablers for %s must require"
644 " that the actor isn't transporting"
645 " another unit."),
650
651 /* Why this is a hard requirement: sanity. */
653 FALSE, FALSE, FALSE,
655 FALSE,
656 N_("All action enablers for %s must require"
657 " that the actor has a home city."),
659
660 /* Why this is a hard requirement: Assumed in the code.
661 * See hrm Bug #772516 - https://www.hostedredmine.com/issues/772516 */
663 FALSE, TRUE, TRUE,
665 TRUE,
666 N_("All action enablers for %s must require"
667 " that the target isn't transporting another"
668 " unit."),
670
671 /* Why this is a hard requirement: sanity. */
673 FALSE, FALSE, TRUE,
675 TRUE,
676 N_("All action enablers for %s must require"
677 " that the target is transporting a unit."),
680 FALSE, FALSE, TRUE,
682 FALSE,
683 N_("All action enablers for %s must require"
684 " that the actor is transported."),
689 FALSE, FALSE, TRUE,
691 FALSE,
692 N_("All action enablers for %s must require"
693 " that the actor is on a livable tile."),
695
696 /* Why this is a hard requirement: sanity. */
698 FALSE, FALSE, TRUE,
700 FALSE,
701 N_("All action enablers for %s must require"
702 " that the actor is transporting a unit."),
705 FALSE, FALSE, TRUE,
707 TRUE,
708 N_("All action enablers for %s must require"
709 " that the target is transported."),
712 FALSE, FALSE, TRUE,
714 TRUE,
715 N_("All action enablers for %s must require"
716 " that the target is on a livable tile."),
718
719 /* Why this is a hard requirement: Use ACTRES_TRANSPORT_DISEMBARK to
720 * disembark. Assumed by the Freeciv code. */
722 FALSE, TRUE, TRUE,
724 FALSE,
725 N_("All action enablers for %s must require"
726 " that the actor isn't transported."),
730
731 /* Why this is a hard requirement: assumed by the Freeciv code. */
733 FALSE, FALSE, TRUE,
735 FALSE,
736 N_("All action enablers for %s must require"
737 " that the actor unit is in a city."),
740
741 /* Why this is a hard requirement: Give meaning to the HutFrighten unit
742 * class flag. The point of it is to keep our options open for how both
743 * entering and frightening a hut at the same tile should be handled.
744 * See hrm Feature #920427 */
746 1,
748 FALSE, TRUE, FALSE,
750 FALSE),
751 N_("All action enablers for %s must require"
752 " that the actor unit doesn't have the"
753 " HutFrighten unit class flag."),
757 1,
759 FALSE, FALSE, FALSE,
761 FALSE),
762 N_("All action enablers for %s must require"
763 " that the actor unit has the HutFrighten"
764 " unit class flag."),
767}
768
769/**********************************************************************/
774{
775 /* Why this is a hard requirement: the "animal can't conquer a city"
776 * rule. Assumed in unit_can_take_over(). */
777 nations_iterate(pnation) {
778 if (nation_barbarian_type(pnation) == ANIMAL_BARBARIAN) {
780 FALSE, TRUE, TRUE,
781 nation_number(pnation)),
782 FALSE,
783 N_("All action enablers for %s must require"
784 " a non animal player actor."),
788 2,
790 FALSE, TRUE, TRUE,
791 nation_number(pnation)),
792 FALSE,
794 FALSE, TRUE, TRUE,
796 TRUE),
797 /* TRANS: error message for ruledit */
798 N_("All action enablers for %s must require"
799 " no city at the target tile or"
800 " a non animal player actor."),
803 }
805}
806
807/**********************************************************************/
811{
812 int i;
813
814 /* Obligatory hard requirements sorted by action result in memory. */
815 for (i = 0; i < ACTRES_NONE; i++) {
816 /* Prepare each action result's storage area. */
818 }
819
820 /* Obligatory hard requirements sorted by action sub result in memory. */
821 for (i = 0; i < ACT_SUB_RES_COUNT; i++) {
822 /* Prepare each action sub result's storage area. */
824 }
825}
826
827/**********************************************************************/
848
849/**********************************************************************/
859
860/**********************************************************************/
char * incite_cost
Definition comments.c:77
#define ACTRES_NONE
Definition fc_types.h:188
#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:484
enum barbarian_type nation_barbarian_type(const struct nation_type *nation)
Definition nation.c:212
#define nations_iterate_end
Definition nation.h:364
#define nations_iterate(NAME_pnation)
Definition nation.h:361
static void oblig_hard_req_reg(struct ae_contra_or *contras, const char *error_message,...)
Definition oblig_reqs.c:210
static void voblig_hard_req_reg(struct ae_contra_or *contras, const char *error_message, va_list args)
Definition oblig_reqs.c:165
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:810
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:830
static void ae_contra_close(struct ae_contra_or *contra)
Definition oblig_reqs.c:79
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:143
static void voblig_hard_req_reg_sub_res(struct ae_contra_or *contras, const char *error_message, va_list args)
Definition oblig_reqs.c:100
void hard_code_oblig_hard_reqs_ruleset(void)
Definition oblig_reqs.c:773
void hard_code_oblig_hard_reqs(void)
Definition oblig_reqs.c:253
struct obligatory_req_vector * oblig_hard_reqs_get(enum action_result res)
Definition oblig_reqs.c:855
struct obligatory_req_vector * oblig_hard_reqs_get_sub(enum action_sub_result res)
Definition oblig_reqs.c:866
static void oblig_hard_req_register(struct requirement contradiction, bool is_target, const char *error_message,...)
Definition oblig_reqs.c:230
#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