Avoid double map_move_cost_unit()
[freeciv.git] / server / advisors / advgoto.c
blob3f20141af877ac18400a52e576333034bf56897a
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 /* common */
19 #include "ai.h"
20 #include "combat.h"
21 #include "game.h"
22 #include "movement.h"
23 #include "unit.h"
24 #include "tile.h"
26 /* aicore */
27 #include "path_finding.h"
29 /* server */
30 #include "maphand.h"
31 #include "srv_log.h"
32 #include "unithand.h"
33 #include "unittools.h"
35 /* server/advisors */
36 #include "advtools.h"
38 #include "advgoto.h"
40 static bool adv_unit_move(struct unit *punit, struct tile *ptile);
42 /**************************************************************************
43 Move a unit along a path without disturbing its activity, role
44 or assigned destination
45 Return FALSE iff we died.
46 **************************************************************************/
47 bool adv_follow_path(struct unit *punit, struct pf_path *path,
48 struct tile *ptile)
50 struct tile *old_tile = punit->goto_tile;
51 enum unit_activity activity = punit->activity;
52 struct extra_type *tgt = punit->activity_target;
53 bool alive;
55 if (punit->moves_left <= 0) {
56 return TRUE;
58 punit->goto_tile = ptile;
59 unit_activity_handling(punit, ACTIVITY_GOTO);
60 alive = adv_unit_execute_path(punit, path);
61 if (alive) {
62 unit_activity_handling(punit, ACTIVITY_IDLE);
63 send_unit_info(NULL, punit); /* FIXME: probably duplicate */
64 unit_activity_handling_targeted(punit, activity, &tgt);
65 punit->goto_tile = old_tile; /* May be NULL. */
66 send_unit_info(NULL, punit);
68 return alive;
72 /*************************************************************************
73 This is a function to execute paths returned by the path-finding engine,
74 for units controlled by advisors.
76 Brings our bodyguard along.
77 Returns FALSE only if died.
78 *************************************************************************/
79 bool adv_unit_execute_path(struct unit *punit, struct pf_path *path)
81 const bool is_ai = unit_owner(punit)->ai_controlled;
82 int i;
84 /* We start with i = 1 for i = 0 is our present position */
85 for (i = 1; i < path->length; i++) {
86 struct tile *ptile = path->positions[i].tile;
87 int id = punit->id;
89 if (same_pos(unit_tile(punit), ptile)) {
90 UNIT_LOG(LOG_DEBUG, punit, "execute_path: waiting this turn");
91 return TRUE;
94 /* We use ai_unit_move() for everything but the last step
95 * of the way so that we abort if unexpected opposition
96 * shows up. Any enemy on the target tile is expected to
97 * be our target and any attack there intentional.
98 * However, do not annoy human players by automatically attacking
99 * using units temporarily under AI control (such as auto-explorers)
102 if (is_ai) {
103 CALL_PLR_AI_FUNC(unit_move, unit_owner(punit), punit, ptile, path, i);
104 } else {
105 (void) adv_unit_move(punit, ptile);
107 if (!game_unit_by_number(id)) {
108 /* Died... */
109 return FALSE;
112 if (!same_pos(unit_tile(punit), ptile) || punit->moves_left <= 0) {
113 /* Stopped (or maybe fought) or ran out of moves */
114 return TRUE;
118 return TRUE;
121 /**************************************************************************
122 Move a unit. Do not attack. Do not leave bodyguard.
123 For advisor controlled units.
125 This function returns only when we have a reply from the server and
126 we can tell the calling function what happened to the move request.
127 (Right now it is not a big problem, since we call the server directly.)
128 **************************************************************************/
129 static bool adv_unit_move(struct unit *punit, struct tile *ptile)
131 struct player *pplayer = unit_owner(punit);
132 int mcost;
134 /* if enemy, stop and give a chance for the human player to
135 handle this case */
136 if (is_enemy_unit_tile(ptile, pplayer)
137 || is_enemy_city_tile(ptile, pplayer)) {
138 UNIT_LOG(LOG_DEBUG, punit, "movement halted due to enemy presence");
139 return FALSE;
142 /* Try not to end move next to an enemy if we can avoid it by waiting */
143 mcost = map_move_cost_unit(punit, ptile);
144 if (punit->moves_left <= mcost
145 && unit_move_rate(punit) > mcost
146 && adv_danger_at(punit, ptile)
147 && !adv_danger_at(punit, unit_tile(punit))) {
148 UNIT_LOG(LOG_DEBUG, punit, "ending move early to stay out of trouble");
149 return FALSE;
152 /* go */
153 unit_activity_handling(punit, ACTIVITY_IDLE);
154 /* Move */
155 (void) unit_move_handling(punit, ptile, FALSE, TRUE, NULL);
157 return TRUE;
160 /**************************************************************************
161 Similar to is_my_zoc(), but with some changes:
162 - destination (x0,y0) need not be adjacent?
163 - don't care about some directions?
165 Fix to bizarre did-not-find bug. Thanks, Katvrr -- Syela
166 **************************************************************************/
167 static bool adv_could_be_my_zoc(struct unit *myunit, struct tile *ptile)
169 if (same_pos(ptile, unit_tile(myunit))) {
170 return FALSE; /* can't be my zoc */
172 if (is_tiles_adjacent(ptile, unit_tile(myunit))
173 && !is_non_allied_unit_tile(ptile, unit_owner(myunit))) {
174 return FALSE;
177 adjc_iterate(ptile, atile) {
178 if (!terrain_has_flag(tile_terrain(atile), TER_NO_ZOC)
179 && is_non_allied_unit_tile(atile, unit_owner(myunit))) {
180 return FALSE;
182 } adjc_iterate_end;
184 return TRUE;
187 /**************************************************************************
188 returns:
189 0 if can't move
190 1 if zoc_ok
191 -1 if zoc could be ok?
193 see also unithand can_unit_move_to_tile_with_notify()
194 **************************************************************************/
195 int adv_could_unit_move_to_tile(struct unit *punit, struct tile *dest_tile)
197 enum unit_move_result reason =
198 unit_move_to_tile_test(punit, ACTIVITY_IDLE, unit_tile(punit),
199 dest_tile, unit_has_type_flag(punit, UTYF_IGZOC),
200 NULL);
202 switch (reason) {
203 case MR_OK:
204 return 1;
206 case MR_ZOC:
207 if (adv_could_be_my_zoc(punit, unit_tile(punit))) {
208 return -1;
210 break;
212 default:
213 break;
215 return 0;
218 /****************************************************************************
219 Attack rating of this kind of unit.
220 ****************************************************************************/
221 int adv_unittype_att_rating(const struct unit_type *punittype, int veteran,
222 int moves_left, int hp)
224 return base_get_attack_power(punittype, veteran, moves_left) * hp
225 * punittype->firepower / POWER_DIVIDER;
228 /****************************************************************************
229 Attack rating of this particular unit assuming that it has a
230 complete move left.
231 ****************************************************************************/
232 int adv_unit_att_rating(const struct unit *punit)
234 return adv_unittype_att_rating(unit_type_get(punit), punit->veteran,
235 SINGLE_MOVE, punit->hp);
238 /****************************************************************************
239 Basic (i.e. not taking attacker specific corections into account)
240 defense rating of this particular unit.
241 ****************************************************************************/
242 int adv_unit_def_rating_basic(const struct unit *punit)
244 return base_get_defense_power(punit) * punit->hp *
245 unit_type_get(punit)->firepower / POWER_DIVIDER;
248 /****************************************************************************
249 Square of the previous function - used in actual computations.
250 ****************************************************************************/
251 int adv_unit_def_rating_basic_sq(const struct unit *punit)
253 int v = adv_unit_def_rating_basic(punit);
254 return v * v;
257 /**************************************************************************
258 Are there dangerous enemies at or adjacent to the tile 'ptile'?
259 **************************************************************************/
260 bool adv_danger_at(struct unit *punit, struct tile *ptile)
262 int a = 0, d, db;
263 struct player *pplayer = unit_owner(punit);
264 struct city *pcity = tile_city(ptile);
265 enum override_bool dc = NO_OVERRIDE;
266 int extras_bonus = 0;
268 /* Give AI code possibility to decide itself */
269 CALL_PLR_AI_FUNC(consider_tile_dangerous, unit_owner(punit), ptile, punit, &dc);
270 if (dc == OVERRIDE_TRUE) {
271 return TRUE;
272 } else if (dc == OVERRIDE_FALSE) {
273 return FALSE;
276 if (pcity && pplayers_allied(city_owner(pcity), unit_owner(punit))
277 && !is_non_allied_unit_tile(ptile, pplayer)) {
278 /* We will be safe in a friendly city */
279 return FALSE;
282 /* Calculate how well we can defend at (x,y) */
283 db = 10 + tile_terrain(ptile)->defense_bonus / 10;
284 extras_bonus += tile_extras_defense_bonus(ptile, unit_type_get(punit));
285 db += (db * extras_bonus) / 100;
286 d = adv_unit_def_rating_basic_sq(punit) * db;
288 adjc_iterate(ptile, ptile1) {
289 if (!map_is_known_and_seen(ptile1, unit_owner(punit), V_MAIN)) {
290 /* We cannot see danger at (ptile1) => assume there is none */
291 continue;
293 unit_list_iterate(ptile1->units, enemy) {
294 if (pplayers_at_war(unit_owner(enemy), unit_owner(punit))
295 && unit_attack_unit_at_tile_result(enemy, punit, ptile) == ATT_OK
296 && unit_attack_units_at_tile_result(enemy, ptile) == ATT_OK) {
297 a += adv_unit_att_rating(enemy);
298 if ((a * a * 10) >= d) {
299 /* The enemies combined strength is too big! */
300 return TRUE;
303 } unit_list_iterate_end;
304 } adjc_iterate_end;
306 return FALSE; /* as good a quick'n'dirty should be -- Syela */
309 /*********************************************************************
310 The value of the units belonging to a given player on a given tile.
311 *********************************************************************/
312 static int stack_value(const struct tile *ptile,
313 const struct player *pplayer)
315 int cost = 0;
317 if (is_stack_vulnerable(ptile)) {
318 unit_list_iterate(ptile->units, punit) {
319 if (unit_owner(punit) == pplayer) {
320 cost += unit_build_shield_cost(punit);
322 } unit_list_iterate_end;
325 return cost;
329 /*********************************************************************
330 How dangerous would it be stop on a particular tile,
331 because of enemy attacks,
332 expressed as the probability of being killed.
334 TODO: This implementation is a kludge until we compute a more accurate
335 probability using the movemap.
336 Also, we should take into account the reduced probability of death
337 if we have a bodyguard travelling with us.
338 *********************************************************************/
339 static double chance_killed_at(const struct tile *ptile,
340 struct adv_risk_cost *risk_cost,
341 const struct pf_parameter *param)
343 double db;
344 int extras_bonus = 0;
345 /* Compute the basic probability */
346 /* WAG */
347 /* In the early stages of a typical game, ferries
348 * are effectively invulnerable (not until Frigates set sail),
349 * so we make seas appear safer.
350 * If we don't do this, the amphibious movement code has too strong a
351 * desire to minimise the length of the path,
352 * leading to poor choice for landing beaches */
353 double p = is_ocean_tile(ptile)? 0.05: 0.15;
355 /* If we are on defensive terrain, we are more likely to survive */
356 db = 10 + tile_terrain(ptile)->defense_bonus / 10;
357 extras_bonus += tile_extras_class_defense_bonus(ptile,
358 utype_class(param->utype));
359 db += (extras_bonus) / 100;
360 p *= 10.0 / db;
362 return p;
365 /*********************************************************************
366 PF stack risk cost. How undesirable is passing through a tile
367 because of risks?
368 Weight by the cost of destruction, for risks that can kill the unit.
370 Why use the build cost when assessing the cost of destruction?
371 The reasoning is thus.
372 - Assume that all our units are doing necessary jobs;
373 none are surplus to requirements.
374 If that is not the case, we have problems elsewhere :-)
375 - Then any units that are destroyed will have to be replaced.
376 - The cost of replacing them will be their build cost.
377 - Therefore the total (re)build cost is a good representation of the
378 the cost of destruction.
379 *********************************************************************/
380 static int stack_risk(const struct tile *ptile,
381 struct adv_risk_cost *risk_cost,
382 const struct pf_parameter *param)
384 double risk = 0;
385 /* Compute the risk of destruction, assuming we will stop at this tile */
386 const double value = risk_cost->base_value
387 + stack_value(ptile, param->owner);
388 const double p_killed = chance_killed_at(ptile, risk_cost, param);
389 double danger = value * p_killed;
391 /* Adjust for the fact that we might not stop at this tile,
392 * and for our fearfulness */
393 risk += danger * risk_cost->fearfulness;
395 /* Adjust for the risk that we might become stuck (for an indefinite period)
396 * if we enter or try to enter the tile. */
397 if (risk_cost->enemy_zoc_cost != 0
398 && (is_non_allied_city_tile(ptile, param->owner)
399 || !is_my_zoc(param->owner, ptile)
400 || is_non_allied_unit_tile(ptile, param->owner))) {
401 /* We could become stuck. */
402 risk += risk_cost->enemy_zoc_cost;
405 return risk;
408 /*********************************************************************
409 PF extra cost call back to avoid creating tall stacks or
410 crossing dangerous tiles.
411 By setting this as an extra-cost call-back, paths will avoid tall stacks.
412 Avoiding tall stacks *all* along a path is useful because a unit following a
413 path might have to stop early because of ZoCs.
414 *********************************************************************/
415 static int prefer_short_stacks(const struct tile *ptile,
416 enum known_type known,
417 const struct pf_parameter *param)
419 return stack_risk(ptile, (struct adv_risk_cost *)param->data, param);
422 /**********************************************************************
423 Set PF call-backs to favour paths that do not create tall stacks
424 or cross dangerous tiles.
425 ***********************************************************************/
426 void adv_avoid_risks(struct pf_parameter *parameter,
427 struct adv_risk_cost *risk_cost,
428 struct unit *punit,
429 const double fearfulness)
431 /* If we stay a short time on each tile, the danger of each individual tile
432 * is reduced. If we do not do this,
433 * we will not favour longer but faster routs. */
434 const double linger_fraction = (double)SINGLE_MOVE / parameter->move_rate;
436 parameter->data = risk_cost;
437 parameter->get_EC = prefer_short_stacks;
438 risk_cost->base_value = unit_build_shield_cost(punit);
439 risk_cost->fearfulness = fearfulness * linger_fraction;
441 risk_cost->enemy_zoc_cost = PF_TURN_FACTOR * 20;