Stop sharing requirement_unit_state_ereq().
[freeciv.git] / common / diptreaty.c
blobc6e32c5316b03873c8635210bac6887dd3c5d871
1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 /* utility */
19 #include "log.h"
20 #include "mem.h"
22 /* common */
23 #include "game.h"
24 #include "player.h"
26 #include "diptreaty.h"
28 /****************************************************************************
29 Returns TRUE iff pplayer could do diplomancy in the game at all.
30 ****************************************************************************/
31 bool diplomacy_possible(const struct player *pplayer1,
32 const struct player *pplayer2)
34 switch (game.info.diplomacy) {
35 case DIPLO_FOR_ALL:
36 return TRUE;
37 case DIPLO_FOR_HUMANS:
38 return (is_human(pplayer1) && is_human(pplayer2));
39 case DIPLO_FOR_AIS:
40 return (is_ai(pplayer1) && is_ai(pplayer2));
41 case DIPLO_NO_AIS:
42 return (!is_ai(pplayer1) || !is_ai(pplayer2));
43 case DIPLO_NO_MIXED:
44 return ((is_human(pplayer1) && is_human(pplayer2))
45 || (is_ai(pplayer1) && is_ai(pplayer2)));
46 case DIPLO_FOR_TEAMS:
47 return players_on_same_team(pplayer1, pplayer2);
48 case DIPLO_DISABLED:
49 return FALSE;
51 log_error("%s(): Unsupported diplomacy variant %d.",
52 __FUNCTION__, game.info.diplomacy);
53 return FALSE;
56 /**************************************************************************
57 Returns TRUE iff pplayer could do diplomatic meetings with aplayer.
58 **************************************************************************/
59 bool could_meet_with_player(const struct player *pplayer,
60 const struct player *aplayer)
62 return (pplayer->is_alive
63 && aplayer->is_alive
64 && pplayer != aplayer
65 && diplomacy_possible(pplayer,aplayer)
66 && get_player_bonus(pplayer, EFT_NO_DIPLOMACY) <= 0
67 && get_player_bonus(aplayer, EFT_NO_DIPLOMACY) <= 0
68 && (player_has_embassy(aplayer, pplayer)
69 || player_has_embassy(pplayer, aplayer)
70 || player_diplstate_get(pplayer, aplayer)->contact_turns_left
71 > 0
72 || player_diplstate_get(aplayer, pplayer)->contact_turns_left
73 > 0));
76 /**************************************************************************
77 Returns TRUE iff pplayer can get intelligence about aplayer.
78 **************************************************************************/
79 bool could_intel_with_player(const struct player *pplayer,
80 const struct player *aplayer)
82 return (pplayer->is_alive
83 && aplayer->is_alive
84 && pplayer != aplayer
85 && (player_diplstate_get(pplayer, aplayer)->contact_turns_left > 0
86 || player_diplstate_get(aplayer, pplayer)->contact_turns_left
87 > 0
88 || player_has_embassy(pplayer, aplayer)));
91 /****************************************************************
92 Initialize treaty structure between two players.
93 *****************************************************************/
94 void init_treaty(struct Treaty *ptreaty,
95 struct player *plr0, struct player *plr1)
97 ptreaty->plr0=plr0;
98 ptreaty->plr1=plr1;
99 ptreaty->accept0 = FALSE;
100 ptreaty->accept1 = FALSE;
101 ptreaty->clauses = clause_list_new();
104 /****************************************************************
105 Free the clauses of a treaty.
106 *****************************************************************/
107 void clear_treaty(struct Treaty *ptreaty)
109 clause_list_iterate(ptreaty->clauses, pclause) {
110 free(pclause);
111 } clause_list_iterate_end;
112 clause_list_destroy(ptreaty->clauses);
115 /****************************************************************
116 Remove clause from treaty
117 *****************************************************************/
118 bool remove_clause(struct Treaty *ptreaty, struct player *pfrom,
119 enum clause_type type, int val)
121 clause_list_iterate(ptreaty->clauses, pclause) {
122 if (pclause->type == type && pclause->from == pfrom
123 && pclause->value == val) {
124 clause_list_remove(ptreaty->clauses, pclause);
125 free(pclause);
127 ptreaty->accept0 = FALSE;
128 ptreaty->accept1 = FALSE;
130 return TRUE;
132 } clause_list_iterate_end;
134 return FALSE;
138 /****************************************************************
139 Add clause to treaty.
140 *****************************************************************/
141 bool add_clause(struct Treaty *ptreaty, struct player *pfrom,
142 enum clause_type type, int val)
144 struct player *pto = (pfrom == ptreaty->plr0
145 ? ptreaty->plr1 : ptreaty->plr0);
146 struct Clause *pclause;
147 enum diplstate_type ds
148 = player_diplstate_get(ptreaty->plr0, ptreaty->plr1)->type;
150 if (!clause_type_is_valid(type)) {
151 log_error("Illegal clause type encountered.");
152 return FALSE;
155 if (type == CLAUSE_ADVANCE && !valid_advance_by_number(val)) {
156 log_error("Illegal tech value %i in clause.", val);
157 return FALSE;
160 if (is_pact_clause(type)
161 && ((ds == DS_PEACE && type == CLAUSE_PEACE)
162 || (ds == DS_ARMISTICE && type == CLAUSE_PEACE)
163 || (ds == DS_ALLIANCE && type == CLAUSE_ALLIANCE)
164 || (ds == DS_CEASEFIRE && type == CLAUSE_CEASEFIRE))) {
165 /* we already have this diplomatic state */
166 log_error("Illegal treaty suggested between %s and %s - they "
167 "already have this treaty level.",
168 nation_rule_name(nation_of_player(ptreaty->plr0)),
169 nation_rule_name(nation_of_player(ptreaty->plr1)));
170 return FALSE;
173 if (type == CLAUSE_EMBASSY && player_has_real_embassy(pto, pfrom)) {
174 /* we already have embassy */
175 log_error("Illegal embassy clause: %s already have embassy with %s.",
176 nation_rule_name(nation_of_player(pto)),
177 nation_rule_name(nation_of_player(pfrom)));
178 return FALSE;
181 if (!game.info.trading_gold && type == CLAUSE_GOLD) {
182 return FALSE;
184 if (!game.info.trading_tech && type == CLAUSE_ADVANCE) {
185 return FALSE;
187 if (!game.info.trading_city && type == CLAUSE_CITY) {
188 return FALSE;
191 clause_list_iterate(ptreaty->clauses, old_clause) {
192 if (old_clause->type == type
193 && old_clause->from == pfrom
194 && old_clause->value == val) {
195 /* same clause already there */
196 return FALSE;
198 if (is_pact_clause(type) &&
199 is_pact_clause(old_clause->type)) {
200 /* pact clause already there */
201 ptreaty->accept0 = FALSE;
202 ptreaty->accept1 = FALSE;
203 old_clause->type = type;
204 return TRUE;
206 if (type == CLAUSE_GOLD && old_clause->type == CLAUSE_GOLD &&
207 old_clause->from == pfrom) {
208 /* gold clause there, different value */
209 ptreaty->accept0 = FALSE;
210 ptreaty->accept1 = FALSE;
211 old_clause->value = val;
212 return TRUE;
214 } clause_list_iterate_end;
216 pclause = fc_malloc(sizeof(*pclause));
218 pclause->type=type;
219 pclause->from=pfrom;
220 pclause->value=val;
222 clause_list_append(ptreaty->clauses, pclause);
224 ptreaty->accept0 = FALSE;
225 ptreaty->accept1 = FALSE;
227 return TRUE;