Freeciv-3.3: /fast/freeciv/nightly/main/ai/default/aiguard.c Source File

Freeciv-3.3

Loading...
Searching...
No Matches
aiguard.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2004 - The Freeciv Project
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
21/* common */
22#include "game.h"
23#include "unit.h"
24
25/* server */
26#include "srv_log.h"
27
28/* ai/default */
29#include "dailog.h"
30#include "daiplayer.h"
31#include "daiunit.h"
32
33#include "aiguard.h"
34
35 enum bodyguard_enum {
36 BODYGUARD_WANTED = -1,
37 BODYGUARD_NONE
38};
39
40/**********************************************************************/
48 void aiguard_check_guard(struct ai_type *ait, const struct unit *guard)
49{
50 struct unit_ai *guard_data = def_ai_unit_data(guard, ait);
51 const struct unit *charge_unit = game_unit_by_number(guard_data->charge);
52 const struct city *charge_city = game_city_by_number(guard_data->charge);
53 const struct player *guard_owner = unit_owner(guard);
54 const struct player *charge_owner = NULL;
55 struct unit_ai *charge_data = NULL;
56
57 fc_assert_ret(BODYGUARD_NONE <= guard_data-> charge);
58 /* IDs always distinct */
59 fc_assert_ret(charge_unit == NULL || charge_city == NULL);
60
61 if (charge_unit) {
62 charge_owner = unit_owner(charge_unit);
63 charge_data = def_ai_unit_data(charge_unit, ait);
64 } else if (charge_city) {
65 charge_owner = city_owner(charge_city);
66 }
67
68 if (charge_unit && charge_data->bodyguard != guard->id) {
69 BODYGUARD_LOG(ait, LOG_DEBUG, guard, "inconsistent guard references");
70 } else if (!charge_unit && !charge_city && 0 < guard_data->charge) {
71 BODYGUARD_LOG(ait, LOG_DEBUG, guard, "dangling guard reference");
72 }
73 if (charge_owner && pplayers_at_war(charge_owner, guard_owner)) {
74 /* Probably due to civil war */
75 BODYGUARD_LOG(ait, LOG_DEBUG, guard, "enemy charge");
76 } else if (charge_owner && charge_owner != guard_owner) {
77 /* Probably sold a city with its supported units. */
78 BODYGUARD_LOG(ait, LOG_DEBUG, guard, "foreign charge");
79 }
80}
81
82/**********************************************************************/
90 void aiguard_check_charge_unit(struct ai_type *ait, const struct unit *charge)
91{
92 struct unit_ai *charge_data = def_ai_unit_data(charge, ait);
93 const struct player *charge_owner = unit_owner(charge);
94 const struct unit *guard = game_unit_by_number(charge_data->bodyguard);
95 struct unit_ai *guard_data = NULL;
96
97 if (guard) {
98 guard_data = def_ai_unit_data(guard, ait);
99 }
100
101 fc_assert_ret(guard == NULL
102 || (guard_data && BODYGUARD_WANTED <= guard_data-> bodyguard));
103
104 if (guard && guard_data->charge != charge->id) {
105 UNIT_LOG(LOG_DEBUG, charge,
106 "inconsistent guard references");
107 } else if (guard && unit_owner(guard) != charge_owner) {
108 UNIT_LOG(LOG_DEBUG, charge, "foreign guard");
109 }
110}
111
112/**********************************************************************/
117 void aiguard_clear_charge(struct ai_type *ait, struct unit *guard)
118{
119 struct unit_ai *guard_data = def_ai_unit_data(guard, ait);
120 struct unit *charge_unit = game_unit_by_number(guard_data->charge);
121 struct city *charge_city = game_city_by_number(guard_data->charge);
122
123 /* IDs always distinct */
124 fc_assert_ret(charge_unit == NULL || charge_city == NULL);
125
126 if (charge_unit) {
127 BODYGUARD_LOG(ait, LOGLEVEL_BODYGUARD, guard, "unassigned (unit)");
128 def_ai_unit_data(charge_unit, ait)->bodyguard = BODYGUARD_NONE;
129 } else if (charge_city) {
130 BODYGUARD_LOG(ait, LOGLEVEL_BODYGUARD, guard, "unassigned (city)");
131 }
132 /* else not assigned or charge was destroyed */
133 guard_data->charge = BODYGUARD_NONE;
134
135 CHECK_GUARD(ait, guard);
136}
137
138/**********************************************************************/
146 void aiguard_clear_guard(struct ai_type *ait, struct unit *charge)
147{
148 struct unit_ai *charge_data = def_ai_unit_data(charge, ait);
149
150 if (0 < charge_data->bodyguard) {
151 struct unit *guard = game_unit_by_number(charge_data->bodyguard);
152
153 if (guard) {
154 struct unit_ai *guard_data = def_ai_unit_data(guard, ait);
155
156 if (guard_data->charge == charge->id) {
157 /* charge doesn't want us anymore */
158 guard_data->charge = BODYGUARD_NONE;
159 }
160 }
161 }
162
163 charge_data->bodyguard = BODYGUARD_NONE;
164
165 CHECK_CHARGE_UNIT(ait, charge);
166}
167
168/**********************************************************************/
173 void aiguard_assign_guard_unit(struct ai_type *ait, struct unit *charge,
174 struct unit *guard)
175{
176 fc_assert_ret(NULL != charge);
177 fc_assert_ret(NULL != guard);
178 fc_assert_ret(charge != guard);
179 fc_assert_ret(unit_owner(charge) == unit_owner(guard));
180
181 /* Remove previous assignment: */
182 aiguard_clear_charge(ait, guard);
183 aiguard_clear_guard(ait, charge);
184
185 def_ai_unit_data(guard, ait)->charge = charge->id;
186 def_ai_unit_data(charge, ait)->bodyguard = guard->id;
187
188 BODYGUARD_LOG(ait, LOGLEVEL_BODYGUARD, guard, "assigned charge");
189 CHECK_GUARD(ait, guard);
190 CHECK_CHARGE_UNIT(ait, charge);
191}
192
193/**********************************************************************/
196 void aiguard_assign_guard_city(struct ai_type *ait, struct city *charge,
197 struct unit *guard)
198{
199 struct unit_ai *guard_data = def_ai_unit_data(guard, ait);
200
201 fc_assert_ret(charge != NULL);
202 fc_assert_ret(guard != NULL);
203 /*
204 * Usually, but not always, city_owner(charge) == unit_owner(guard).
205 */
206
207 if (0 < guard_data->charge
208 && guard_data->charge != charge->id) {
209 /* Remove previous assignment: */
210 aiguard_clear_charge(ait, guard);
211 }
212
213 guard_data->charge = charge->id;
214 if (city_owner(charge) != unit_owner(guard)) {
215 /* Peculiar, but not always an error */
216 BODYGUARD_LOG(ait, LOGLEVEL_BODYGUARD, guard, "assigned foreign charge");
217 } else {
218 BODYGUARD_LOG(ait, LOGLEVEL_BODYGUARD, guard, "assigned charge");
219 }
220
221 CHECK_GUARD(ait, guard);
222}
223
224/**********************************************************************/
227 void aiguard_request_guard(struct ai_type *ait, struct unit *punit)
228{
229 /* Remove previous assignment */
230 aiguard_clear_guard(ait, punit);
231
232 UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "requests a guard");
233 def_ai_unit_data(punit, ait)->bodyguard = BODYGUARD_WANTED;
234
235 CHECK_CHARGE_UNIT(ait, punit);
236}
237
238/**********************************************************************/
241 bool aiguard_wanted(struct ai_type *ait, struct unit *charge)
242{
243 CHECK_CHARGE_UNIT(ait, charge);
244 return (def_ai_unit_data(charge, ait)->bodyguard == BODYGUARD_WANTED);
245}
246
247/**********************************************************************/
250 bool aiguard_has_charge(struct ai_type *ait, struct unit *guard)
251{
252 CHECK_GUARD(ait, guard);
253 return (def_ai_unit_data(guard, ait)->charge != BODYGUARD_NONE);
254}
255
256/**********************************************************************/
259 bool aiguard_has_guard(struct ai_type *ait, struct unit *charge)
260{
261 CHECK_CHARGE_UNIT(ait, charge);
262 return (0 < def_ai_unit_data(charge, ait)->bodyguard);
263}
264
265/**********************************************************************/
269 struct unit *aiguard_guard_of(struct ai_type *ait, struct unit *charge)
270{
271 CHECK_CHARGE_UNIT(ait, charge);
272 return game_unit_by_number(def_ai_unit_data(charge, ait)->bodyguard);
273}
274
275/**********************************************************************/
279 struct unit *aiguard_charge_unit(struct ai_type *ait, struct unit *guard)
280{
281 CHECK_GUARD(ait, guard);
282 return game_unit_by_number(def_ai_unit_data(guard, ait)->charge);
283}
284
285/**********************************************************************/
289 struct city *aiguard_charge_city(struct ai_type *ait, struct unit *guard)
290{
291 CHECK_GUARD(ait, guard);
292 return game_city_by_number(def_ai_unit_data(guard, ait)->charge);
293}
294
295/**********************************************************************/
299 void aiguard_update_charge(struct ai_type *ait, struct unit *guard)
300{
301 struct unit_ai *guard_data = def_ai_unit_data(guard, ait);
302 const struct unit *charge_unit = game_unit_by_number(guard_data->charge);
303 const struct city *charge_city = game_city_by_number(guard_data->charge);
304 const struct player *guard_owner = unit_owner(guard);
305 const struct player *charge_owner = NULL;
306
307 fc_assert_ret(BODYGUARD_NONE <= guard_data->charge);
308 /* IDs always distinct */
309 fc_assert_ret(charge_unit == NULL || charge_city == NULL);
310
311 if (charge_unit) {
312 charge_owner = unit_owner(charge_unit);
313 } else if (charge_city) {
314 charge_owner = city_owner(charge_city);
315 }
316
317 if (!charge_unit && !charge_city && 0 < guard_data->charge) {
318 guard_data->charge = BODYGUARD_NONE;
319 BODYGUARD_LOG(ait, LOGLEVEL_BODYGUARD, guard, "charge was destroyed");
320 }
321 if (charge_owner && charge_owner != guard_owner) {
322 BODYGUARD_LOG(ait, LOGLEVEL_BODYGUARD, guard, "charge transferred, dismiss");
323 aiguard_clear_charge(ait, guard);
324 }
325
326 CHECK_GUARD(ait, guard);
327}
aiguard_charge_city
struct city * aiguard_charge_city(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:289
aiguard_clear_charge
void aiguard_clear_charge(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:117
aiguard_request_guard
void aiguard_request_guard(struct ai_type *ait, struct unit *punit)
Definition aiguard.c:227
aiguard_has_guard
bool aiguard_has_guard(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:259
aiguard_assign_guard_unit
void aiguard_assign_guard_unit(struct ai_type *ait, struct unit *charge, struct unit *guard)
Definition aiguard.c:173
aiguard_wanted
bool aiguard_wanted(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:241
aiguard_assign_guard_city
void aiguard_assign_guard_city(struct ai_type *ait, struct city *charge, struct unit *guard)
Definition aiguard.c:196
aiguard_charge_unit
struct unit * aiguard_charge_unit(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:279
bodyguard_enum
bodyguard_enum
Definition aiguard.c:35
BODYGUARD_NONE
@ BODYGUARD_NONE
Definition aiguard.c:37
BODYGUARD_WANTED
@ BODYGUARD_WANTED
Definition aiguard.c:36
aiguard_clear_guard
void aiguard_clear_guard(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:146
aiguard_guard_of
struct unit * aiguard_guard_of(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:269
aiguard_has_charge
bool aiguard_has_charge(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:250
aiguard_update_charge
void aiguard_update_charge(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:299
aiguard_check_charge_unit
void aiguard_check_charge_unit(struct ai_type *ait, const struct unit *charge)
Definition aiguard.c:90
aiguard_check_guard
void aiguard_check_guard(struct ai_type *ait, const struct unit *guard)
Definition aiguard.c:48
aiguard.h
CHECK_CHARGE_UNIT
#define CHECK_CHARGE_UNIT(ait, charge)
Definition aiguard.h:22
CHECK_GUARD
#define CHECK_GUARD(ait, guard)
Definition aiguard.h:21
city_owner
#define city_owner(_pcity_)
Definition city.h:563
incite_cost
char * incite_cost
Definition comments.c:74
dailog.h
BODYGUARD_LOG
#define BODYGUARD_LOG(ait, loglevel, punit, msg,...)
Definition dailog.h:69
daiplayer.h
def_ai_unit_data
static struct unit_ai * def_ai_unit_data(const struct unit *punit, struct ai_type *deftype)
Definition daiplayer.h:48
daiunit.h
punit
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
game_unit_by_number
struct unit * game_unit_by_number(int id)
Definition game.c:115
game_city_by_number
struct city * game_city_by_number(int id)
Definition game.c:106
game.h
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
LOG_DEBUG
@ LOG_DEBUG
Definition log.h:34
pplayers_at_war
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1388
srv_log.h
UNIT_LOG
#define UNIT_LOG(loglevel, punit, msg,...)
Definition srv_log.h:98
LOGLEVEL_BODYGUARD
#define LOGLEVEL_BODYGUARD
Definition srv_log.h:30
ai_type
Definition ai.h:50
city
Definition city.h:320
player
Definition player.h:249
unit_ai
Definition daiunit.h:32
unit_ai::bodyguard
int bodyguard
Definition daiunit.h:36
unit_ai::charge
int charge
Definition daiunit.h:37
unit
Definition unit.h:140
unit.h
unit_owner
#define unit_owner(_pu)
Definition unit.h:396