Freeciv-3.1
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 */
29#include "ailog.h"
30#include "aiplayer.h"
31#include "aitools.h"
32#include "aiunit.h"
33
34#include "aiguard.h"
35
40
41/**********************************************************************/
49void aiguard_check_guard(struct ai_type *ait, const struct unit *guard)
50{
51 struct unit_ai *guard_data = def_ai_unit_data(guard, ait);
52 const struct unit *charge_unit = game_unit_by_number(guard_data->charge);
53 const struct city *charge_city = game_city_by_number(guard_data->charge);
54 const struct player *guard_owner = unit_owner(guard);
55 const struct player *charge_owner = NULL;
56 struct unit_ai *charge_data = NULL;
57
58 fc_assert_ret(BODYGUARD_NONE <= guard_data->charge);
59 /* IDs always distinct */
60 fc_assert_ret(charge_unit == NULL || charge_city == NULL);
61
62 if (charge_unit) {
63 charge_owner = unit_owner(charge_unit);
64 charge_data = def_ai_unit_data(charge_unit, ait);
65 } else if (charge_city) {
66 charge_owner = city_owner(charge_city);
67 }
68
69 if (charge_unit && charge_data->bodyguard != guard->id) {
70 BODYGUARD_LOG(ait, LOG_DEBUG, guard, "inconsistent guard references");
71 } else if (!charge_unit && !charge_city && 0 < guard_data->charge) {
72 BODYGUARD_LOG(ait, LOG_DEBUG, guard, "dangling guard reference");
73 }
74 if (charge_owner && pplayers_at_war(charge_owner, guard_owner)) {
75 /* Probably due to civil war */
76 BODYGUARD_LOG(ait, LOG_DEBUG, guard, "enemy charge");
77 } else if (charge_owner && charge_owner != guard_owner) {
78 /* Probably sold a city with its supported units. */
79 BODYGUARD_LOG(ait, LOG_DEBUG, guard, "foreign charge");
80 }
81}
82
83/**********************************************************************/
91void aiguard_check_charge_unit(struct ai_type *ait, const struct unit *charge)
92{
93 struct unit_ai *charge_data = def_ai_unit_data(charge, ait);
94 const struct player *charge_owner = unit_owner(charge);
95 const struct unit *guard = game_unit_by_number(charge_data->bodyguard);
96 struct unit_ai *guard_data = NULL;
97
98 if (guard) {
99 guard_data = def_ai_unit_data(guard, ait);
100 }
101
102 fc_assert_ret(guard == NULL
103 || (guard_data && BODYGUARD_WANTED <= guard_data->bodyguard));
104
105 if (guard && guard_data->charge != charge->id) {
107 "inconsistent guard references");
108 } else if (guard && unit_owner(guard) != charge_owner) {
109 UNIT_LOG(LOG_DEBUG, charge, "foreign guard");
110 }
111}
112
113/**********************************************************************/
118void aiguard_clear_charge(struct ai_type *ait, struct unit *guard)
119{
120 struct unit_ai *guard_data = def_ai_unit_data(guard, ait);
121 struct unit *charge_unit = game_unit_by_number(guard_data->charge);
122 struct city *charge_city = game_city_by_number(guard_data->charge);
123
124 /* IDs always distinct */
125 fc_assert_ret(charge_unit == NULL || charge_city == NULL);
126
127 if (charge_unit) {
128 BODYGUARD_LOG(ait, LOGLEVEL_BODYGUARD, guard, "unassigned (unit)");
129 def_ai_unit_data(charge_unit, ait)->bodyguard = BODYGUARD_NONE;
130 } else if (charge_city) {
131 BODYGUARD_LOG(ait, LOGLEVEL_BODYGUARD, guard, "unassigned (city)");
132 }
133 /* else not assigned or charge was destroyed */
134 guard_data->charge = BODYGUARD_NONE;
135
136 CHECK_GUARD(ait, guard);
137}
138
139/**********************************************************************/
147void aiguard_clear_guard(struct ai_type *ait, struct unit *charge)
148{
149 struct unit_ai *charge_data = def_ai_unit_data(charge, ait);
150
151 if (0 < charge_data->bodyguard) {
152 struct unit *guard = game_unit_by_number(charge_data->bodyguard);
153
154 if (guard) {
155 struct unit_ai *guard_data = def_ai_unit_data(guard, ait);
156
157 if (guard_data->charge == charge->id) {
158 /* charge doesn't want us anymore */
159 guard_data->charge = BODYGUARD_NONE;
160 }
161 }
162 }
163
164 charge_data->bodyguard = BODYGUARD_NONE;
165
167}
168
169/**********************************************************************/
175 struct unit *guard)
176{
177 fc_assert_ret(NULL != charge);
178 fc_assert_ret(NULL != guard);
179 fc_assert_ret(charge != guard);
181
182 /* Remove previous assignment: */
183 aiguard_clear_charge(ait, guard);
185
186 def_ai_unit_data(guard, ait)->charge = charge->id;
187 def_ai_unit_data(charge, ait)->bodyguard = guard->id;
188
189 BODYGUARD_LOG(ait, LOGLEVEL_BODYGUARD, guard, "assigned charge");
190 CHECK_GUARD(ait, guard);
192}
193
194/**********************************************************************/
198 struct unit *guard)
199{
200 struct unit_ai *guard_data = def_ai_unit_data(guard, ait);
201
202 fc_assert_ret(charge != NULL);
203 fc_assert_ret(guard != NULL);
204 /*
205 * Usually, but not always, city_owner(charge) == unit_owner(guard).
206 */
207
208 if (0 < guard_data->charge
209 && guard_data->charge != charge->id) {
210 /* Remove previous assignment: */
211 aiguard_clear_charge(ait, guard);
212 }
213
214 guard_data->charge = charge->id;
215 if (city_owner(charge) != unit_owner(guard)) {
216 /* Peculiar, but not always an error */
217 BODYGUARD_LOG(ait, LOGLEVEL_BODYGUARD, guard, "assigned foreign charge");
218 } else {
219 BODYGUARD_LOG(ait, LOGLEVEL_BODYGUARD, guard, "assigned charge");
220 }
221
222 CHECK_GUARD(ait, guard);
223}
224
225/**********************************************************************/
228void aiguard_request_guard(struct ai_type *ait, struct unit *punit)
229{
230 /* Remove previous assignment */
232
233 UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "requests a guard");
235
237}
238
239/**********************************************************************/
242bool aiguard_wanted(struct ai_type *ait, struct unit *charge)
243{
246}
247
248/**********************************************************************/
251bool aiguard_has_charge(struct ai_type *ait, struct unit *guard)
252{
253 CHECK_GUARD(ait, guard);
254 return (def_ai_unit_data(guard, ait)->charge != BODYGUARD_NONE);
255}
256
257/**********************************************************************/
260bool aiguard_has_guard(struct ai_type *ait, struct unit *charge)
261{
263 return (0 < def_ai_unit_data(charge, ait)->bodyguard);
264}
265
266/**********************************************************************/
270struct unit *aiguard_guard_of(struct ai_type *ait, struct unit *charge)
271{
272 CHECK_CHARGE_UNIT(ait, charge);
273 return game_unit_by_number(def_ai_unit_data(charge, ait)->bodyguard);
274}
275
276/**********************************************************************/
280struct unit *aiguard_charge_unit(struct ai_type *ait, struct unit *guard)
281{
282 CHECK_GUARD(ait, guard);
283 return game_unit_by_number(def_ai_unit_data(guard, ait)->charge);
284}
285
286/**********************************************************************/
290struct city *aiguard_charge_city(struct ai_type *ait, struct unit *guard)
291{
292 CHECK_GUARD(ait, guard);
293 return game_city_by_number(def_ai_unit_data(guard, ait)->charge);
294}
295
296/**********************************************************************/
300void aiguard_update_charge(struct ai_type *ait, struct unit *guard)
301{
302 struct unit_ai *guard_data = def_ai_unit_data(guard, ait);
303 const struct unit *charge_unit = game_unit_by_number(guard_data->charge);
304 const struct city *charge_city = game_city_by_number(guard_data->charge);
305 const struct player *guard_owner = unit_owner(guard);
306 const struct player *charge_owner = NULL;
307
308 fc_assert_ret(BODYGUARD_NONE <= guard_data->charge);
309 /* IDs always distinct */
310 fc_assert_ret(charge_unit == NULL || charge_city == NULL);
311
312 if (charge_unit) {
313 charge_owner = unit_owner(charge_unit);
314 } else if (charge_city) {
315 charge_owner = city_owner(charge_city);
316 }
317
318 if (!charge_unit && !charge_city && 0 < guard_data->charge) {
319 guard_data->charge = BODYGUARD_NONE;
320 BODYGUARD_LOG(ait, LOGLEVEL_BODYGUARD, guard, "charge was destroyed");
321 }
322 if (charge_owner && charge_owner != guard_owner) {
323 BODYGUARD_LOG(ait, LOGLEVEL_BODYGUARD, guard, "charge transferred, dismiss");
324 aiguard_clear_charge(ait, guard);
325 }
326
327 CHECK_GUARD(ait, guard);
328}
struct city * aiguard_charge_city(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:290
void aiguard_clear_charge(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:118
void aiguard_request_guard(struct ai_type *ait, struct unit *punit)
Definition aiguard.c:228
bool aiguard_has_guard(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:260
void aiguard_assign_guard_unit(struct ai_type *ait, struct unit *charge, struct unit *guard)
Definition aiguard.c:174
bool aiguard_wanted(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:242
void aiguard_assign_guard_city(struct ai_type *ait, struct city *charge, struct unit *guard)
Definition aiguard.c:197
struct unit * aiguard_charge_unit(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:280
bodyguard_enum
Definition aiguard.c:36
@ BODYGUARD_NONE
Definition aiguard.c:38
@ BODYGUARD_WANTED
Definition aiguard.c:37
void aiguard_clear_guard(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:147
struct unit * aiguard_guard_of(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:270
bool aiguard_has_charge(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:251
void aiguard_update_charge(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:300
void aiguard_check_charge_unit(struct ai_type *ait, const struct unit *charge)
Definition aiguard.c:91
void aiguard_check_guard(struct ai_type *ait, const struct unit *guard)
Definition aiguard.c:49
#define CHECK_CHARGE_UNIT(ait, charge)
Definition aiguard.h:22
#define CHECK_GUARD(ait, guard)
Definition aiguard.h:21
#define BODYGUARD_LOG(ait, loglevel, punit, msg,...)
Definition ailog.h:69
static struct unit_ai * def_ai_unit_data(const struct unit *punit, struct ai_type *deftype)
Definition aiplayer.h:48
#define city_owner(_pcity_)
Definition city.h:543
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:73
struct unit * game_unit_by_number(int id)
Definition game.c:111
struct city * game_city_by_number(int id)
Definition game.c:102
#define fc_assert_ret(condition)
Definition log.h:191
@ LOG_DEBUG
Definition log.h:34
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1364
#define UNIT_LOG(loglevel, punit, msg,...)
Definition srv_log.h:98
#define LOGLEVEL_BODYGUARD
Definition srv_log.h:30
Definition ai.h:50
Definition city.h:309
int bodyguard
Definition aiunit.h:36
int charge
Definition aiunit.h:37
Definition unit.h:138
int id
Definition unit.h:145
#define unit_owner(_pu)
Definition unit.h:394