Freeciv21
Develop your civilization from humble roots to a global empire
diptreaty.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 // utility
15 #include "log.h"
16 
17 // common
18 #include "diptreaty.h"
19 #include "game.h"
20 #include "nation.h"
21 #include "player.h"
22 
23 static struct clause_info clause_infos[CLAUSE_COUNT];
24 
28 bool diplomacy_possible(const struct player *pplayer1,
29  const struct player *pplayer2)
30 {
31  switch (game.info.diplomacy) {
32  case DIPLO_FOR_ALL:
33  return true;
34  case DIPLO_FOR_HUMANS:
35  return (is_human(pplayer1) && is_human(pplayer2));
36  case DIPLO_FOR_AIS:
37  return (is_ai(pplayer1) && is_ai(pplayer2));
38  case DIPLO_NO_AIS:
39  return (!is_ai(pplayer1) || !is_ai(pplayer2));
40  case DIPLO_NO_MIXED:
41  return ((is_human(pplayer1) && is_human(pplayer2))
42  || (is_ai(pplayer1) && is_ai(pplayer2)));
43  case DIPLO_FOR_TEAMS:
44  return players_on_same_team(pplayer1, pplayer2);
45  case DIPLO_DISABLED:
46  return false;
47  }
48  qCritical("%s(): Unsupported diplomacy variant %d.", __FUNCTION__,
49  game.info.diplomacy);
50  return false;
51 }
52 
56 bool could_meet_with_player(const struct player *pplayer,
57  const struct player *aplayer)
58 {
59  return (
60  pplayer->is_alive && aplayer->is_alive && pplayer != aplayer
61  && diplomacy_possible(pplayer, aplayer)
62  && get_player_bonus(pplayer, EFT_NO_DIPLOMACY) <= 0
63  && get_player_bonus(aplayer, EFT_NO_DIPLOMACY) <= 0
64  && (player_has_embassy(aplayer, pplayer)
65  || player_has_embassy(pplayer, aplayer)
66  || player_diplstate_get(pplayer, aplayer)->contact_turns_left > 0
67  || player_diplstate_get(aplayer, pplayer)->contact_turns_left
68  > 0));
69 }
70 
74 bool could_intel_with_player(const struct player *pplayer,
75  const struct player *aplayer)
76 {
77  return (
78  pplayer->is_alive && aplayer->is_alive && pplayer != aplayer
79  && (player_diplstate_get(pplayer, aplayer)->contact_turns_left > 0
80  || player_diplstate_get(aplayer, pplayer)->contact_turns_left > 0
81  || player_has_embassy(pplayer, aplayer)));
82 }
83 
87 void init_treaty(struct Treaty *ptreaty, struct player *plr0,
88  struct player *plr1)
89 {
90  ptreaty->plr0 = plr0;
91  ptreaty->plr1 = plr1;
92  ptreaty->accept0 = false;
93  ptreaty->accept1 = false;
94  ptreaty->clauses = clause_list_new();
95 }
96 
100 void clear_treaty(struct Treaty *ptreaty)
101 {
102  clause_list_iterate(ptreaty->clauses, pclause) { delete (pclause); }
104  clause_list_destroy(ptreaty->clauses);
105 }
106 
110 bool remove_clause(struct Treaty *ptreaty, struct player *pfrom,
111  enum clause_type type, int val)
112 {
113  clause_list_iterate(ptreaty->clauses, pclause)
114  {
115  if (pclause->type == type && pclause->from == pfrom
116  && pclause->value == val) {
117  clause_list_remove(ptreaty->clauses, pclause);
118  delete pclause;
119 
120  ptreaty->accept0 = false;
121  ptreaty->accept1 = false;
122 
123  return true;
124  }
125  }
127 
128  return false;
129 }
130 
134 bool add_clause(struct Treaty *ptreaty, struct player *pfrom,
135  enum clause_type type, int val)
136 {
137  struct player *pto =
138  (pfrom == ptreaty->plr0 ? ptreaty->plr1 : ptreaty->plr0);
139  struct Clause *pclause;
140  enum diplstate_type ds =
141  player_diplstate_get(ptreaty->plr0, ptreaty->plr1)->type;
142 
143  if (!clause_type_is_valid(type)) {
144  qCritical("Illegal clause type encountered.");
145  return false;
146  }
147 
148  if (type == CLAUSE_ADVANCE && !valid_advance_by_number(val)) {
149  qCritical("Illegal tech value %i in clause.", val);
150  return false;
151  }
152 
153  if (is_pact_clause(type)
154  && ((ds == DS_PEACE && type == CLAUSE_PEACE)
155  || (ds == DS_ARMISTICE && type == CLAUSE_PEACE)
156  || (ds == DS_ALLIANCE && type == CLAUSE_ALLIANCE)
157  || (ds == DS_CEASEFIRE && type == CLAUSE_CEASEFIRE))) {
158  // we already have this diplomatic state
159  qCritical("Illegal treaty suggested between %s and %s - they "
160  "already have this treaty level.",
163  return false;
164  }
165 
166  if (type == CLAUSE_EMBASSY && player_has_real_embassy(pto, pfrom)) {
167  // we already have embassy
168  qCritical("Illegal embassy clause: %s already have embassy with %s.",
171  return false;
172  }
173 
174  if (!clause_enabled(type, pfrom, pto)) {
175  return false;
176  }
177 
178  if (!are_reqs_active(pfrom, pto, nullptr, nullptr, nullptr, nullptr,
179  nullptr, nullptr, nullptr, nullptr,
180  &clause_infos[type].giver_reqs, RPT_POSSIBLE)
181  || !are_reqs_active(pto, pfrom, nullptr, nullptr, nullptr, nullptr,
182  nullptr, nullptr, nullptr, nullptr,
183  &clause_infos[type].receiver_reqs, RPT_POSSIBLE)) {
184  return false;
185  }
186 
187  clause_list_iterate(ptreaty->clauses, old_clause)
188  {
189  if (old_clause->type == type && old_clause->from == pfrom
190  && old_clause->value == val) {
191  // same clause already there
192  return false;
193  }
194  if (is_pact_clause(type) && is_pact_clause(old_clause->type)) {
195  // pact clause already there
196  ptreaty->accept0 = false;
197  ptreaty->accept1 = false;
198  old_clause->type = type;
199  return true;
200  }
201  if (type == CLAUSE_GOLD && old_clause->type == CLAUSE_GOLD
202  && old_clause->from == pfrom) {
203  // gold clause there, different value
204  ptreaty->accept0 = false;
205  ptreaty->accept1 = false;
206  old_clause->value = val;
207  return true;
208  }
209  }
211 
212  pclause = new Clause;
213 
214  pclause->type = type;
215  pclause->from = pfrom;
216  pclause->value = val;
217 
218  clause_list_append(ptreaty->clauses, pclause);
219 
220  ptreaty->accept0 = false;
221  ptreaty->accept1 = false;
222 
223  return true;
224 }
225 
230 {
231  int i;
232 
233  for (i = 0; i < CLAUSE_COUNT; i++) {
234  clause_infos[i].type = clause_type(i);
235  clause_infos[i].enabled = false;
236  requirement_vector_init(&(clause_infos[i].giver_reqs));
237  requirement_vector_init(&(clause_infos[i].receiver_reqs));
238  }
239 }
240 
245 {
246  int i;
247 
248  for (i = 0; i < CLAUSE_COUNT; i++) {
249  requirement_vector_free(&(clause_infos[i].giver_reqs));
250  requirement_vector_free(&(clause_infos[i].receiver_reqs));
251  }
252 }
253 
257 struct clause_info *clause_info_get(enum clause_type type)
258 {
259  fc_assert(type >= 0 && type < CLAUSE_COUNT);
260 
261  return &clause_infos[type];
262 }
263 
272 bool clause_enabled(enum clause_type type, struct player *from,
273  struct player *to)
274 {
275  Q_UNUSED(from)
276  Q_UNUSED(to)
277  struct clause_info *info = &clause_infos[type];
278 
279  if (!info->enabled) {
280  return false;
281  }
282 
283  if (!game.info.trading_gold && type == CLAUSE_GOLD) {
284  return false;
285  }
286  if (!game.info.trading_tech && type == CLAUSE_ADVANCE) {
287  return false;
288  }
289  if (!game.info.trading_city && type == CLAUSE_CITY) {
290  return false;
291  }
292 
293  return true;
294 }
bool add_clause(struct Treaty *ptreaty, struct player *pfrom, enum clause_type type, int val)
Add clause to treaty.
Definition: diptreaty.cpp:134
bool diplomacy_possible(const struct player *pplayer1, const struct player *pplayer2)
Returns TRUE iff pplayer could do diplomancy in the game at all.
Definition: diptreaty.cpp:28
struct clause_info * clause_info_get(enum clause_type type)
Free memory associated with clause infos.
Definition: diptreaty.cpp:257
bool clause_enabled(enum clause_type type, struct player *from, struct player *to)
Is clause enabled in this game? Currently this does not consider clause requirements that may change ...
Definition: diptreaty.cpp:272
void clear_treaty(struct Treaty *ptreaty)
Free the clauses of a treaty.
Definition: diptreaty.cpp:100
void init_treaty(struct Treaty *ptreaty, struct player *plr0, struct player *plr1)
Initialize treaty structure between two players.
Definition: diptreaty.cpp:87
static struct clause_info clause_infos[CLAUSE_COUNT]
Definition: diptreaty.cpp:23
void clause_infos_free()
Free memory associated with clause infos.
Definition: diptreaty.cpp:244
void clause_infos_init()
Initialize clause info structures.
Definition: diptreaty.cpp:229
bool remove_clause(struct Treaty *ptreaty, struct player *pfrom, enum clause_type type, int val)
Remove clause from treaty.
Definition: diptreaty.cpp:110
bool could_intel_with_player(const struct player *pplayer, const struct player *aplayer)
Returns TRUE iff pplayer can get intelligence about aplayer.
Definition: diptreaty.cpp:74
bool could_meet_with_player(const struct player *pplayer, const struct player *aplayer)
Returns TRUE iff pplayer could do diplomatic meetings with aplayer.
Definition: diptreaty.cpp:56
#define clause_list_iterate_end
Definition: diptreaty.h:61
#define clause_list_iterate(clauselist, pclause)
Definition: diptreaty.h:59
#define is_pact_clause(x)
Definition: diptreaty.h:43
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Returns the effect bonus for a player.
Definition: effects.cpp:673
@ DIPLO_NO_MIXED
Definition: fc_types.h:877
@ DIPLO_FOR_TEAMS
Definition: fc_types.h:878
@ DIPLO_NO_AIS
Definition: fc_types.h:876
@ DIPLO_FOR_HUMANS
Definition: fc_types.h:874
@ DIPLO_FOR_ALL
Definition: fc_types.h:873
@ DIPLO_FOR_AIS
Definition: fc_types.h:875
@ DIPLO_DISABLED
Definition: fc_types.h:879
@ RPT_POSSIBLE
Definition: fc_types.h:567
struct civ_game game
Definition: game.cpp:47
#define fc_assert(condition)
Definition: log.h:89
const char * nation_rule_name(const struct nation_type *pnation)
Return the (untranslated) rule name of the nation (adjective form).
Definition: nation.cpp:115
struct nation_type * nation_of_player(const struct player *pplayer)
Return the nation of a player.
Definition: nation.cpp:419
bool players_on_same_team(const struct player *pplayer1, const struct player *pplayer2)
Return TRUE if players are in the same team.
Definition: player.cpp:1405
bool player_has_real_embassy(const struct player *pplayer, const struct player *pplayer2)
Returns whether pplayer has a real embassy with pplayer2, established from a diplomat,...
Definition: player.cpp:206
bool player_has_embassy(const struct player *pplayer, const struct player *pplayer2)
Check if pplayer has an embassy with pplayer2.
Definition: player.cpp:195
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Returns diplomatic state type between two players.
Definition: player.cpp:288
#define is_ai(plr)
Definition: player.h:227
#define is_human(plr)
Definition: player.h:226
bool are_reqs_active(const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct action *target_action, const struct requirement_vector *reqs, const enum req_problem_type prob_type, const enum vision_layer vision_layer, const enum national_intelligence nintel)
Checks the requirement(s) to see if they are active on the given target.
enum clause_type type
Definition: diptreaty.h:64
struct player * from
Definition: diptreaty.h:65
int value
Definition: diptreaty.h:66
struct player * plr0
Definition: diptreaty.h:70
bool accept0
Definition: diptreaty.h:71
bool accept1
Definition: diptreaty.h:71
struct clause_list * clauses
Definition: diptreaty.h:72
struct player * plr1
Definition: diptreaty.h:70
struct packet_game_info info
Definition: game.h:80
enum clause_type type
Definition: diptreaty.h:47
bool enabled
Definition: diptreaty.h:48
enum diplstate_type type
Definition: player.h:193
Definition: player.h:231
bool is_alive
Definition: player.h:250
struct advance * valid_advance_by_number(const Tech_type_id id)
Returns pointer when the advance "exists" in this game, returns nullptr otherwise.
Definition: tech.cpp:154