Freeciv-3.3: /fast/freeciv/nightly/main/common/diptreaty.c Source File

Freeciv-3.3

Loading...
Searching...
No Matches
diptreaty.c
Go to the documentation of this file.
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.
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 "log.h"
20#include "mem.h"
21
22/* common */
23#include "game.h"
24#include "nation.h"
25#include "player.h"
26
27#include "diptreaty.h"
28
29 static struct clause_info clause_infos[CLAUSE_COUNT];
30
31 static struct treaty_list *treaties = NULL;
32
33/**********************************************************************/
36 bool diplomacy_possible(const struct player *pplayer1,
37 const struct player *pplayer2)
38{
39 switch (game.info.diplomacy) {
40 case DIPLO_FOR_ALL:
41 return TRUE;
42 case DIPLO_FOR_HUMANS:
43 return (is_human(pplayer1) && is_human(pplayer2));
44 case DIPLO_FOR_AIS:
45 return (is_ai(pplayer1) && is_ai(pplayer2));
46 case DIPLO_NO_AIS:
47 return (!is_ai(pplayer1) || !is_ai(pplayer2));
48 case DIPLO_NO_MIXED:
49 return ((is_human(pplayer1) && is_human(pplayer2))
50 || (is_ai(pplayer1) && is_ai(pplayer2)));
51 case DIPLO_FOR_TEAMS:
52 return players_on_same_team(pplayer1, pplayer2);
53 case DIPLO_DISABLED:
54 return FALSE;
55 }
56 log_error("%s(): Unsupported diplomacy variant %d.",
57 __FUNCTION__, game.info.diplomacy);
58 return FALSE;
59}
60
61/**********************************************************************/
64 bool could_meet_with_player(const struct player *pplayer,
65 const struct player *aplayer)
66{
67 return (pplayer->is_alive
68 && aplayer->is_alive
69 && pplayer != aplayer
70 && diplomacy_possible(pplayer,aplayer)
71 && get_player_bonus(pplayer, EFT_NO_DIPLOMACY) <= 0
72 && get_player_bonus(aplayer, EFT_NO_DIPLOMACY) <= 0
73 && (player_has_embassy(aplayer, pplayer)
74 || player_has_embassy(pplayer, aplayer)
75 || player_diplstate_get(pplayer, aplayer)->contact_turns_left
76 > 0
77 || player_diplstate_get(aplayer, pplayer)->contact_turns_left
78 > 0));
79}
80
81/**********************************************************************/
84 bool could_intel_with_player(const struct player *pplayer,
85 const struct player *aplayer)
86{
87 return (pplayer->is_alive
88 && aplayer->is_alive
89 && pplayer != aplayer
90 && (player_diplstate_get(pplayer, aplayer)->contact_turns_left > 0
91 || player_diplstate_get(aplayer, pplayer)->contact_turns_left
92 > 0
93 || team_has_embassy(pplayer->team, aplayer)));
94}
95
96/**********************************************************************/
99 void init_treaty(struct Treaty *ptreaty,
100 struct player *plr0, struct player *plr1)
101{
102 ptreaty->plr0=plr0;
103 ptreaty->plr1=plr1;
104 ptreaty->accept0 = FALSE;
105 ptreaty->accept1 = FALSE;
106 ptreaty->clauses = clause_list_new();
107}
108
109/**********************************************************************/
112 void clear_treaty(struct Treaty *ptreaty)
113{
114 clause_list_iterate(ptreaty->clauses, pclause) {
115 free(pclause);
116 } clause_list_iterate_end;
117 clause_list_destroy(ptreaty->clauses);
118}
119
120/**********************************************************************/
123 bool remove_clause(struct Treaty *ptreaty, struct player *pfrom,
124 enum clause_type type, int val)
125{
126 clause_list_iterate(ptreaty->clauses, pclause) {
127 if (pclause->type == type && pclause->from == pfrom
128 && pclause->value == val) {
129 clause_list_remove(ptreaty->clauses, pclause);
130 free(pclause);
131
132 ptreaty->accept0 = FALSE;
133 ptreaty->accept1 = FALSE;
134
135 return TRUE;
136 }
137 } clause_list_iterate_end;
138
139 return FALSE;
140}
141
142/**********************************************************************/
145 bool add_clause(struct Treaty *ptreaty, struct player *pfrom,
146 enum clause_type type, int val,
147 struct player *client_player)
148{
149 struct player *pto = (pfrom == ptreaty->plr0
150 ? ptreaty->plr1 : ptreaty->plr0);
151 struct Clause *pclause;
152 enum diplstate_type ds
153 = player_diplstate_get(ptreaty->plr0, ptreaty->plr1)->type;
154
155 if (!clause_type_is_valid(type)) {
156 log_error("Illegal clause type encountered.");
157 return FALSE;
158 }
159
160 if (type == CLAUSE_ADVANCE && !valid_advance_by_number(val)) {
161 log_error("Illegal tech value %i in clause.", val);
162 return FALSE;
163 }
164
165 if (is_pact_clause(type)
166 && ((ds == DS_PEACE && type == CLAUSE_PEACE)
167 || (ds == DS_ARMISTICE && type == CLAUSE_PEACE)
168 || (ds == DS_ALLIANCE && type == CLAUSE_ALLIANCE)
169 || (ds == DS_CEASEFIRE && type == CLAUSE_CEASEFIRE))) {
170 /* we already have this diplomatic state */
171 log_error("Illegal treaty suggested between %s and %s - they "
172 "already have this treaty level.",
173 nation_rule_name(nation_of_player(ptreaty->plr0)),
174 nation_rule_name(nation_of_player(ptreaty->plr1)));
175 return FALSE;
176 }
177
178 if (type == CLAUSE_EMBASSY && player_has_real_embassy(pto, pfrom)) {
179 /* We already have embassy */
180 log_error("Illegal embassy clause: %s already have embassy with %s.",
181 nation_rule_name(nation_of_player(pto)),
182 nation_rule_name(nation_of_player(pfrom)));
183 return FALSE;
184 }
185
186 if (!clause_enabled(type)) {
187 return FALSE;
188 }
189
190 /* Leave it to the server to decide if the other party can meet
191 * the requirements. */
192 if (client_player == NULL || client_player == pfrom) {
193 if (!are_reqs_active(&(const struct req_context) { .player = pfrom },
194 pto, &clause_infos[type].giver_reqs, RPT_POSSIBLE)) {
195 return FALSE;
196 }
197 }
198 if (client_player == NULL || client_player == pto) {
199 if (!are_reqs_active(&(const struct req_context) { .player = pto },
200 pfrom, &clause_infos[type].receiver_reqs,
201 RPT_POSSIBLE)) {
202 return FALSE;
203 }
204 }
205 if (client_player == NULL) {
206 if (!are_reqs_active(&(const struct req_context) { .player = pfrom },
207 pfrom, &clause_infos[type].either_reqs,
208 RPT_POSSIBLE)
209 && !are_reqs_active(&(const struct req_context) { .player = pto },
210 pfrom, &clause_infos[type].either_reqs,
211 RPT_POSSIBLE)) {
212 return FALSE;
213 }
214 }
215
216 clause_list_iterate(ptreaty->clauses, old_clause) {
217 if (old_clause->type == type
218 && old_clause->from == pfrom
219 && old_clause->value == val) {
220 /* same clause already there */
221 return FALSE;
222 }
223 if (is_pact_clause(type)
224 && is_pact_clause(old_clause->type)) {
225 /* pact clause already there */
226 ptreaty->accept0 = FALSE;
227 ptreaty->accept1 = FALSE;
228 old_clause->type = type;
229 return TRUE;
230 }
231 if (type == CLAUSE_GOLD && old_clause->type == CLAUSE_GOLD
232 && old_clause->from == pfrom) {
233 /* gold clause there, different value */
234 ptreaty->accept0 = FALSE;
235 ptreaty->accept1 = FALSE;
236 old_clause->value = val;
237 return TRUE;
238 }
239 } clause_list_iterate_end;
240
241 pclause = fc_malloc(sizeof(*pclause));
242
243 pclause->type = type;
244 pclause->from = pfrom;
245 pclause->value = val;
246
247 clause_list_append(ptreaty->clauses, pclause);
248
249 ptreaty->accept0 = FALSE;
250 ptreaty->accept1 = FALSE;
251
252 return TRUE;
253}
254
255/**********************************************************************/
258 void clause_infos_init(void)
259{
260 int i;
261
262 for (i = 0; i < CLAUSE_COUNT; i++) {
263 clause_infos[i].type = i;
264 clause_infos[i].enabled = FALSE;
265 requirement_vector_init(&(clause_infos[i].giver_reqs));
266 requirement_vector_init(&(clause_infos[i].receiver_reqs));
267 requirement_vector_init(&(clause_infos[i].either_reqs));
268 }
269}
270
271/**********************************************************************/
274 void clause_infos_free(void)
275{
276 int i;
277
278 for (i = 0; i < CLAUSE_COUNT; i++) {
279 requirement_vector_free(&(clause_infos[i].giver_reqs));
280 requirement_vector_free(&(clause_infos[i].receiver_reqs));
281 requirement_vector_free(&(clause_infos[i].either_reqs));
282 }
283}
284
285/**********************************************************************/
288 struct clause_info *clause_info_get(enum clause_type type)
289{
290 fc_assert(type >= 0 && type < CLAUSE_COUNT);
291
292 return &clause_infos[type];
293}
294
295/**********************************************************************/
301 bool clause_enabled(enum clause_type type)
302{
303 struct clause_info *info = &clause_infos[type];
304
305 if (!info->enabled) {
306 return FALSE;
307 }
308
309 if (!game.info.trading_gold && type == CLAUSE_GOLD) {
310 return FALSE;
311 }
312 if (!game.info.trading_tech && type == CLAUSE_ADVANCE) {
313 return FALSE;
314 }
315 if (!game.info.trading_city && type == CLAUSE_CITY) {
316 return FALSE;
317 }
318
319 return TRUE;
320}
321
322/**********************************************************************/
325 void treaties_init(void)
326{
327 treaties = treaty_list_new();
328}
329
330/**********************************************************************/
333 void treaties_free(void)
334{
335 free_treaties();
336
337 treaty_list_destroy(treaties);
338 treaties = NULL;
339}
340
341/**********************************************************************/
344 void free_treaties(void)
345{
346 /* Free memory allocated for treaties */
347 treaty_list_iterate(treaties, pt) {
348 clear_treaty(pt);
349 free(pt);
350 } treaty_list_iterate_end;
351
352 treaty_list_clear(treaties);
353}
354
355/**********************************************************************/
358 struct Treaty *find_treaty(struct player *plr0, struct player *plr1)
359{
360 treaty_list_iterate(treaties, ptreaty) {
361 if ((ptreaty->plr0 == plr0 && ptreaty->plr1 == plr1)
362 || (ptreaty->plr0 == plr1 && ptreaty->plr1 == plr0)) {
363 return ptreaty;
364 }
365 } treaty_list_iterate_end;
366
367 return NULL;
368}
369
370/**********************************************************************/
373 void treaty_add(struct Treaty *ptreaty)
374{
375 treaty_list_prepend(treaties, ptreaty);
376}
377
378/**********************************************************************/
381 void treaty_remove(struct Treaty *ptreaty)
382{
383 treaty_list_remove(treaties, ptreaty);
384
385 clear_treaty(ptreaty);
386 free(ptreaty);
387}
388
389/**********************************************************************/
392 void treaties_iterate(treaty_cb cb, void *data)
393{
394 treaty_list_iterate(treaties, ptr) {
395 cb(ptr, data);
396 } treaty_list_iterate_end;
397}
client_player
#define client_player()
Definition client_main.h:106
incite_cost
char * incite_cost
Definition comments.c:74
ptreaty
struct Treaty * ptreaty
Definition diplodlg_g.h:28
treaties
static struct treaty_list * treaties
Definition diptreaty.c:31
diplomacy_possible
bool diplomacy_possible(const struct player *pplayer1, const struct player *pplayer2)
Definition diptreaty.c:36
clause_infos_init
void clause_infos_init(void)
Definition diptreaty.c:258
clause_infos_free
void clause_infos_free(void)
Definition diptreaty.c:274
free_treaties
void free_treaties(void)
Definition diptreaty.c:344
treaties_init
void treaties_init(void)
Definition diptreaty.c:325
clear_treaty
void clear_treaty(struct Treaty *ptreaty)
Definition diptreaty.c:112
init_treaty
void init_treaty(struct Treaty *ptreaty, struct player *plr0, struct player *plr1)
Definition diptreaty.c:99
treaties_iterate
void treaties_iterate(treaty_cb cb, void *data)
Definition diptreaty.c:392
add_clause
bool add_clause(struct Treaty *ptreaty, struct player *pfrom, enum clause_type type, int val, struct player *client_player)
Definition diptreaty.c:145
clause_enabled
bool clause_enabled(enum clause_type type)
Definition diptreaty.c:301
treaty_add
void treaty_add(struct Treaty *ptreaty)
Definition diptreaty.c:373
clause_infos
static struct clause_info clause_infos[CLAUSE_COUNT]
Definition diptreaty.c:29
remove_clause
bool remove_clause(struct Treaty *ptreaty, struct player *pfrom, enum clause_type type, int val)
Definition diptreaty.c:123
treaty_remove
void treaty_remove(struct Treaty *ptreaty)
Definition diptreaty.c:381
could_intel_with_player
bool could_intel_with_player(const struct player *pplayer, const struct player *aplayer)
Definition diptreaty.c:84
treaties_free
void treaties_free(void)
Definition diptreaty.c:333
find_treaty
struct Treaty * find_treaty(struct player *plr0, struct player *plr1)
Definition diptreaty.c:358
clause_info_get
struct clause_info * clause_info_get(enum clause_type type)
Definition diptreaty.c:288
could_meet_with_player
bool could_meet_with_player(const struct player *pplayer, const struct player *aplayer)
Definition diptreaty.c:64
diptreaty.h
treaty_cb
void(* treaty_cb)(struct Treaty *, void *data)
Definition diptreaty.h:124
clause_list_iterate_end
#define clause_list_iterate_end
Definition diptreaty.h:71
treaty_list_iterate
#define treaty_list_iterate(list, p)
Definition diptreaty.h:111
clause_list_iterate
#define clause_list_iterate(clauselist, pclause)
Definition diptreaty.h:69
treaty_list_iterate_end
#define treaty_list_iterate_end
Definition diptreaty.h:113
is_pact_clause
#define is_pact_clause(x)
Definition diptreaty.h:51
get_player_bonus
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:828
DIPLO_NO_MIXED
@ DIPLO_NO_MIXED
Definition fc_types.h:1064
DIPLO_FOR_TEAMS
@ DIPLO_FOR_TEAMS
Definition fc_types.h:1065
DIPLO_NO_AIS
@ DIPLO_NO_AIS
Definition fc_types.h:1063
DIPLO_FOR_HUMANS
@ DIPLO_FOR_HUMANS
Definition fc_types.h:1061
DIPLO_FOR_ALL
@ DIPLO_FOR_ALL
Definition fc_types.h:1060
DIPLO_FOR_AIS
@ DIPLO_FOR_AIS
Definition fc_types.h:1062
DIPLO_DISABLED
@ DIPLO_DISABLED
Definition fc_types.h:1066
RPT_POSSIBLE
@ RPT_POSSIBLE
Definition fc_types.h:707
game
struct civ_game game
Definition game.c:62
game.h
type
GType type
Definition repodlgs.c:1313
log.h
fc_assert
#define fc_assert(condition)
Definition log.h:176
log_error
#define log_error(message,...)
Definition log.h:103
mem.h
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
nation_rule_name
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
nation_of_player
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:444
nation.h
players_on_same_team
bool players_on_same_team(const struct player *pplayer1, const struct player *pplayer2)
Definition player.c:1480
player_has_real_embassy
bool player_has_real_embassy(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:240
team_has_embassy
bool team_has_embassy(const struct team *pteam, const struct player *tgt_player)
Definition player.c:220
player_diplstate_get
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:324
player_has_embassy
bool player_has_embassy(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:208
player.h
is_ai
#define is_ai(plr)
Definition player.h:232
is_human
#define is_human(plr)
Definition player.h:231
are_reqs_active
bool are_reqs_active(const struct req_context *context, const struct player *other_player, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
Definition requirements.c:5705
Clause
Definition diptreaty.h:73
Treaty
Definition diptreaty.h:79
Treaty::plr0
struct player * plr0
Definition diptreaty.h:80
Treaty::accept0
bool accept0
Definition diptreaty.h:81
Treaty::accept1
bool accept1
Definition diptreaty.h:81
Treaty::clauses
struct clause_list * clauses
Definition diptreaty.h:82
Treaty::plr1
struct player * plr1
Definition diptreaty.h:80
civ_game::info
struct packet_game_info info
Definition game.h:89
clause_info
Definition diptreaty.h:55
clause_info::receiver_reqs
struct requirement_vector receiver_reqs
Definition diptreaty.h:59
clause_info::giver_reqs
struct requirement_vector giver_reqs
Definition diptreaty.h:58
clause_info::type
enum clause_type type
Definition diptreaty.h:56
clause_info::either_reqs
struct requirement_vector either_reqs
Definition diptreaty.h:60
clause_info::enabled
bool enabled
Definition diptreaty.h:57
packet_game_info::trading_city
bool trading_city
Definition packets_gen.h:244
packet_game_info::diplomacy
enum diplomacy_mode diplomacy
Definition packets_gen.h:155
packet_game_info::trading_gold
bool trading_gold
Definition packets_gen.h:245
packet_game_info::trading_tech
bool trading_tech
Definition packets_gen.h:246
player_diplstate::type
enum diplstate_type type
Definition player.h:199
player
Definition player.h:249
player::team
struct team * team
Definition player.h:261
player::is_alive
bool is_alive
Definition player.h:268
req_context
Definition requirements.h:100
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
valid_advance_by_number
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176