Freeciv-3.2
Loading...
Searching...
No Matches
advgoto.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/* 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"
25
26/* aicore */
27#include "path_finding.h"
28
29/* server */
30#include "maphand.h"
31#include "srv_log.h"
32#include "unithand.h"
33#include "unittools.h"
34
35/* server/advisors */
36#include "advtools.h"
37
38#include "advgoto.h"
39
40static bool adv_unit_move(struct unit *punit, struct tile *ptile);
41
42/**********************************************************************/
47bool adv_follow_path(struct unit *punit, struct pf_path *path,
48 struct tile *ptile)
49{
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;
54
55 if (punit->moves_left <= 0) {
56 return TRUE;
57 }
58 punit->goto_tile = ptile;
61 if (alive) {
62 if (activity != ACTIVITY_GOTO) {
63 /* Only go via ACTIVITY_IDLE if we are actually changing the activity */
65 send_unit_info(NULL, punit); /* FIXME: probably duplicate */
67 }
68 punit->goto_tile = old_tile; /* May be NULL. */
70 }
71 return alive;
72}
73
74
75/**********************************************************************/
82bool adv_unit_execute_path(struct unit *punit, struct pf_path *path)
83{
84 const bool is_plr_ai = is_ai(unit_owner(punit));
85 int i;
86
87 /* We start with i = 1 for i = 0 is our present position */
88 for (i = 1; i < path->length; i++) {
89 struct tile *ptile = path->positions[i].tile;
90 int id = punit->id;
91
92 if (same_pos(unit_tile(punit), ptile)) {
93#ifdef PF_WAIT_DEBUG
95#if PF_WAIT_DEBUG & 1
97#if PF_WAIT_DEBUG & (2 | 4)
98 ||
99#endif
100#endif
101#if PF_WAIT_DEBUG & 2
103#if PF_WAIT_DEBUG & 4
104 ||
105#endif
106#endif
107#if PF_WAIT_DEBUG & 4
109#endif
110 , "%s waits at %d,%d for no visible profit",
111 unit_rule_name(punit), TILE_XY(ptile));
112#endif
113 UNIT_LOG(LOG_DEBUG, punit, "execute_path: waiting this turn");
114 return TRUE;
115 }
116
117 /* We use ai_unit_move() for everything but the last step
118 * of the way so that we abort if unexpected opposition
119 * shows up. Any enemy on the target tile is expected to
120 * be our target and any attack there intentional.
121 * However, do not annoy human players by automatically attacking
122 * using units temporarily under AI control (such as auto-explorers)
123 */
124
125 if (is_plr_ai) {
127 } else {
128 (void) adv_unit_move(punit, ptile);
129 }
130 if (!game_unit_by_number(id)) {
131 /* Died... */
132 return FALSE;
133 }
134
135 if (!same_pos(unit_tile(punit), ptile) || punit->moves_left <= 0) {
136 /* Stopped (or maybe fought) or ran out of moves */
137 return TRUE;
138 }
139 }
140
141 return TRUE;
142}
143
144/**********************************************************************/
152static bool adv_unit_move(struct unit *punit, struct tile *ptile)
153{
154 struct action *paction;
155 struct player *pplayer = unit_owner(punit);
156 struct unit *ptrans = NULL;
157 const struct civ_map *nmap = &(wld.map);
158
159 /* If enemy, stop and give a chance for the human player to
160 handle this case */
161 if (is_enemy_unit_tile(ptile, pplayer)
162 || is_enemy_city_tile(ptile, pplayer)) {
163 UNIT_LOG(LOG_DEBUG, punit, "movement halted due to enemy presence");
164 return FALSE;
165 }
166
167 /* Select move kind. */
169 && ((ptrans = transporter_for_unit_at(punit, ptile)))
171 punit, ptrans)) {
172 /* "Transport Embark". */
174 } else if (!can_unit_survive_at_tile(nmap, punit, ptile)
175 && ptrans != NULL
177 punit, ptrans)) {
178 /* "Transport Embark 2". */
180 } else if (!can_unit_survive_at_tile(nmap, punit, ptile)
181 && ptrans != NULL
183 punit, ptrans)) {
184 /* "Transport Embark 3". */
186 } else if (!can_unit_survive_at_tile(nmap, punit, ptile)
187 && ptrans != NULL
189 punit, ptrans)) {
190 /* "Transport Embark 4". */
193 punit, ptile, NULL)) {
194 /* "Transport Disembark". */
197 punit, ptile, NULL)) {
198 /* "Transport Disembark 2". */
201 punit, ptile, NULL)) {
202 /* "Transport Disembark 3". */
205 punit, ptile, NULL)) {
206 /* "Transport Disembark 4". */
209 punit, ptile, NULL)) {
210 /* "Enter Hut". */
213 punit, ptile, NULL)) {
214 /* "Enter Hut 2". */
217 punit, ptile, NULL)) {
218 /* "Enter Hut 3". */
221 punit, ptile, NULL)) {
222 /* "Enter Hut 4". */
225 punit, ptile, NULL)) {
226 /* "Frighten Hut". */
229 punit, ptile, NULL)) {
230 /* "Frighten Hut 2". */
233 punit, ptile, NULL)) {
234 /* "Frighten Hut 3". */
237 punit, ptile, NULL)) {
238 /* "Frighten Hut 4". */
241 punit, ptile, NULL)) {
242 /* "Unit Move". */
245 punit, ptile, NULL)) {
246 /* "Unit Move 2". */
248 } else {
249 /* "Unit Move 3". */
251 }
252
253 /* Try not to end move next to an enemy if we can avoid it by waiting */
256 /* The unit will have to move it self rather than being moved. */
257 int mcost = map_move_cost_unit(nmap, punit, ptile);
258
259 if (paction) {
260 struct tile *from_tile;
261
262 /* Ugly hack to understand the OnNativeTile unit state requirements
263 * used in the Action_Success_Actor_Move_Cost effect. */
267 punit->tile = ptile;
268
270
272 }
273
274 if (punit->moves_left <= mcost
275 && unit_move_rate(punit) > mcost
276 && adv_danger_at(punit, ptile)
279 "ending move early to stay out of trouble");
280 return FALSE;
281 }
282 }
283
284 /* go */
286 /* Move */
287 /* TODO: Differentiate (server side AI) player from server side agent
288 * working for (possibly AI) player by using ACT_REQ_PLAYER and
289 * ACT_REQ_SS_AGENT */
290 if (paction && ptrans
292 /* "Transport Embark". */
294 0, "", action_number(paction));
295 } else if (paction
304 /* "Transport Disembark", "Transport Disembark 2", "Enter Hut",
305 * "Frighten Hut" or "Unit Move". */
307 0, "", action_number(paction));
308 }
309
310 return TRUE;
311}
312
313/**********************************************************************/
320static bool adv_could_be_my_zoc(struct unit *myunit, struct tile *ptile)
321{
322 struct tile *utile = unit_tile(myunit);
323 struct player *owner;
324 struct civ_map *cmap = &(wld.map);
325
326 if (same_pos(ptile, utile)) {
327 return FALSE; /* Can't be my zoc */
328 }
329
331 if (is_tiles_adjacent(ptile, utile)
332 && !is_non_allied_unit_tile(ptile, owner)) {
333 return FALSE;
334 }
335
336 adjc_iterate(cmap, ptile, atile) {
339 return FALSE;
340 }
342
343 return TRUE;
344}
345
346/**********************************************************************/
354int adv_could_unit_move_to_tile(struct unit *punit, struct tile *dest_tile)
355{
359 TRUE, NULL, FALSE);
360
361 switch (reason) {
362 case MR_OK:
363 return 1;
364
365 case MR_ZOC:
367 return -1;
368 }
369 break;
370
371 default:
372 break;
373 };
374 return 0;
375}
376
377/**********************************************************************/
380int adv_unittype_att_rating(const struct unit_type *punittype, int veteran,
381 int moves_left, int hp)
382{
383 return base_get_attack_power(punittype, veteran, moves_left) * hp
384 * punittype->firepower / POWER_DIVIDER;
385}
386
387/**********************************************************************/
396
397/**********************************************************************/
406
407/**********************************************************************/
411{
413
414 return v * v;
415}
416
417/**********************************************************************/
420bool adv_danger_at(struct unit *punit, struct tile *ptile)
421{
422 int a = 0, d, db;
423 struct player *pplayer = unit_owner(punit);
424 struct city *pcity = tile_city(ptile);
426 int extras_bonus = 0;
427
428 /* Give AI code possibility to decide itself */
429 CALL_PLR_AI_FUNC(consider_tile_dangerous, unit_owner(punit), ptile, punit, &dc);
430 if (dc == OVERRIDE_TRUE) {
431 return TRUE;
432 } else if (dc == OVERRIDE_FALSE) {
433 return FALSE;
434 }
435
436 if (pcity && pplayers_allied(city_owner(pcity), unit_owner(punit))
437 && !is_non_allied_unit_tile(ptile, pplayer)) {
438 /* We will be safe in a friendly city */
439 return FALSE;
440 }
441
442 /* Calculate how well we can defend at (x,y) */
443 db = 10 + tile_terrain(ptile)->defense_bonus / 10;
445 db += (db * extras_bonus) / 100;
447
448 adjc_iterate(&(wld.map), ptile, ptile1) {
450 /* We cannot see danger at (ptile1) => assume there is none */
451 continue;
452 }
456 == ATT_OK)
458 == ATT_OK)) {
460 if ((a * a * 10) >= d) {
461 /* The enemies combined strength is too big! */
462 return TRUE;
463 }
464 }
467
468 return FALSE; /* as good a quick'n'dirty should be -- Syela */
469}
470
471/**********************************************************************/
474static int stack_value(const struct tile *ptile,
475 const struct player *pplayer)
476{
477 int cost = 0;
478
479 if (is_stack_vulnerable(ptile)) {
480 unit_list_iterate(ptile->units, punit) {
481 if (unit_owner(punit) == pplayer) {
483 }
485 }
486
487 return cost;
488}
489
490/**********************************************************************/
500static double chance_killed_at(const struct tile *ptile,
501 struct adv_risk_cost *risk_cost,
502 const struct pf_parameter *param)
503{
504 double db;
505 int extras_bonus = 0;
506 /* Compute the basic probability */
507 /* WAG */
508 /* In the early stages of a typical game, ferries
509 * are effectively invulnerable (not until Frigates set sail),
510 * so we make seas appear safer.
511 * If we don't do this, the amphibious movement code has too strong a
512 * desire to minimise the length of the path,
513 * leading to poor choice for landing beaches */
514 double p = is_ocean_tile(ptile)? 0.05: 0.15;
515
516 /* If we are on defensive terrain, we are more likely to survive */
517 db = 10 + tile_terrain(ptile)->defense_bonus / 10;
519 utype_class(param->utype));
520 db += (extras_bonus) / 100;
521 p *= 10.0 / db;
522
523 return p;
524}
525
526/**********************************************************************/
541static unsigned stack_risk(const struct tile *ptile,
542 struct adv_risk_cost *risk_cost,
543 const struct pf_parameter *param)
544{
545 double risk = 0;
546 /* Compute the risk of destruction, assuming we will stop at this tile */
547 const double value = risk_cost->base_value
548 + stack_value(ptile, param->owner);
549 const double p_killed = chance_killed_at(ptile, risk_cost, param);
550 double danger = value * p_killed;
551
552 /* Adjust for the fact that we might not stop at this tile,
553 * and for our fearfulness */
554 risk += danger * risk_cost->fearfulness;
555
556 /* Adjust for the risk that we might become stuck (for an indefinite period)
557 * if we enter or try to enter the tile. */
558 if (risk_cost->enemy_zoc_cost != 0
559 && (is_non_allied_city_tile(ptile, param->owner)
560 || !is_plr_zoc_srv(param->owner, ptile, param->map)
561 || is_non_allied_unit_tile(ptile, param->owner))) {
562 /* We could become stuck. */
563 risk += risk_cost->enemy_zoc_cost;
564 }
565
566 return risk;
567}
568
569/**********************************************************************/
576static unsigned prefer_short_stacks(const struct tile *ptile,
577 enum known_type known,
578 const struct pf_parameter *param)
579{
580 return stack_risk(ptile, (struct adv_risk_cost *)param->data, param);
581}
582
583/**********************************************************************/
587void adv_avoid_risks(struct pf_parameter *parameter,
588 struct adv_risk_cost *risk_cost,
589 struct unit *punit,
590 const double fearfulness)
591{
592 /* If we stay a short time on each tile, the danger of each individual tile
593 * is reduced. If we do not do this,
594 * we will not favour longer but faster routs. */
595 const double linger_fraction = (double)SINGLE_MOVE / parameter->move_rate;
596
597 parameter->data = risk_cost;
598 parameter->get_EC = prefer_short_stacks;
600 risk_cost->fearfulness = fearfulness * linger_fraction;
601
602 risk_cost->enemy_zoc_cost = PF_TURN_FACTOR * 20;
603}
int action_number(const struct action *action)
Definition actions.c:1969
bool is_action_enabled_unit_on_tile(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4082
bool is_action_enabled_unit_on_unit(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct unit *target_unit)
Definition actions.c:3918
static struct action * action_by_number(action_id act_id)
Definition actions.h:635
#define action_has_result(_act_, _res_)
Definition actions.h:431
bool adv_follow_path(struct unit *punit, struct pf_path *path, struct tile *ptile)
Definition advgoto.c:47
int adv_unit_def_rating_basic_squared(const struct unit *punit)
Definition advgoto.c:410
static int stack_value(const struct tile *ptile, const struct player *pplayer)
Definition advgoto.c:474
int adv_unit_def_rating_basic(const struct unit *punit)
Definition advgoto.c:401
static unsigned prefer_short_stacks(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Definition advgoto.c:576
static unsigned stack_risk(const struct tile *ptile, struct adv_risk_cost *risk_cost, const struct pf_parameter *param)
Definition advgoto.c:541
bool adv_danger_at(struct unit *punit, struct tile *ptile)
Definition advgoto.c:420
static bool adv_unit_move(struct unit *punit, struct tile *ptile)
Definition advgoto.c:152
static double chance_killed_at(const struct tile *ptile, struct adv_risk_cost *risk_cost, const struct pf_parameter *param)
Definition advgoto.c:500
int adv_unittype_att_rating(const struct unit_type *punittype, int veteran, int moves_left, int hp)
Definition advgoto.c:380
int adv_unit_att_rating(const struct unit *punit)
Definition advgoto.c:391
static bool adv_could_be_my_zoc(struct unit *myunit, struct tile *ptile)
Definition advgoto.c:320
int adv_could_unit_move_to_tile(struct unit *punit, struct tile *dest_tile)
Definition advgoto.c:354
void adv_avoid_risks(struct pf_parameter *parameter, struct adv_risk_cost *risk_cost, struct unit *punit, const double fearfulness)
Definition advgoto.c:587
bool adv_unit_execute_path(struct unit *punit, struct pf_path *path)
Definition advgoto.c:82
#define POWER_DIVIDER
Definition advtools.h:32
#define CALL_PLR_AI_FUNC(_func, _player,...)
Definition ai.h:377
static bool is_non_allied_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:770
static bool is_enemy_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:734
#define city_owner(_pcity_)
Definition city.h:563
bool is_stack_vulnerable(const struct tile *ptile)
Definition combat.c:989
enum unit_attack_result unit_attack_units_at_tile_result(const struct unit *punit, const struct action *paction, const struct tile *ptile)
Definition combat.c:256
int base_get_attack_power(const struct unit_type *punittype, int veteran, int moves_left)
Definition combat.c:545
enum unit_attack_result unit_attack_unit_at_tile_result(const struct unit *punit, const struct action *paction, const struct unit *pdefender, const struct tile *dest_tile)
Definition combat.c:122
int base_get_defense_power(const struct unit *punit)
Definition combat.c:569
@ ATT_OK
Definition combat.h:35
char * incite_cost
Definition comments.c:75
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
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 int cost
Definition dialogs_g.h:74
override_bool
Definition fc_types.h:94
@ OVERRIDE_TRUE
Definition fc_types.h:94
@ NO_OVERRIDE
Definition fc_types.h:94
@ OVERRIDE_FALSE
Definition fc_types.h:94
struct world wld
Definition game.c:63
struct unit * game_unit_by_number(int id)
Definition game.c:116
struct city * owner
Definition citydlg.c:226
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define fc_assert(condition)
Definition log.h:176
@ LOG_DEBUG
Definition log.h:34
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Definition map.c:931
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:940
#define adjc_iterate_end
Definition map.h:433
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:428
static int map_move_cost_unit(const struct civ_map *nmap, struct unit *punit, const struct tile *ptile)
Definition map.h:293
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:920
enum unit_move_result unit_move_to_tile_test(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity, const struct tile *src_tile, const struct tile *dst_tile, bool igzoc, bool enter_transport, struct unit *embark_to, bool enter_enemy_city)
Definition movement.c:630
int unit_move_rate(const struct unit *punit)
Definition movement.c:90
bool can_unit_survive_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:491
#define SINGLE_MOVE
Definition movement.h:26
unit_move_result
Definition movement.h:34
@ MR_OK
Definition movement.h:35
@ MR_ZOC
Definition movement.h:40
#define PF_TURN_FACTOR
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1388
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1405
#define is_ai(plr)
Definition player.h:230
#define UNIT_LOG(loglevel, punit, msg,...)
Definition srv_log.h:98
Definition city.h:320
const struct civ_map * map
const struct player * owner
unsigned(* get_EC)(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
const struct unit_type * utype
unsigned length
struct pf_position * positions
struct tile * tile
Definition tile.h:50
struct unit_list * units
Definition tile.h:58
int firepower
Definition unittype.h:525
Definition unit.h:138
enum unit_activity activity
Definition unit.h:157
int moves_left
Definition unit.h:150
int id
Definition unit.h:145
int hp
Definition unit.h:151
int fuel
Definition unit.h:153
struct tile * tile
Definition unit.h:140
struct extra_type * activity_target
Definition unit.h:164
struct tile * goto_tile
Definition unit.h:155
int veteran
Definition unit.h:152
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define is_ocean_tile(ptile)
Definition terrain.h:303
#define terrain_has_flag(terr, flag)
Definition terrain.h:283
int tile_extras_class_defense_bonus(const struct tile *ptile, const struct unit_class *pclass)
Definition tile.c:242
int tile_extras_defense_bonus(const struct tile *ptile, const struct unit_type *punittype)
Definition tile.c:233
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:88
known_type
Definition tile.h:35
#define tile_terrain(_tile)
Definition tile.h:110
#define TILE_XY(ptile)
Definition tile.h:43
int unit_pays_mp_for_action(const struct action *paction, const struct unit *punit)
Definition unit.c:2135
struct unit * transporter_for_unit_at(const struct unit *pcargo, const struct tile *ptile)
Definition unit.c:1922
bool is_plr_zoc_srv(const struct player *pplayer, const struct tile *ptile0, const struct civ_map *zmap)
Definition unit.c:1387
#define unit_tile(_pu)
Definition unit.h:397
static bool is_enemy_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:420
#define unit_owner(_pu)
Definition unit.h:396
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:432
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity)
Definition unithand.c:6471
void unit_do_action(struct player *pplayer, const int actor_id, const int target_id, const int sub_tgt_id, const char *name, const action_id action_type)
Definition unithand.c:3293
bool unit_activity_handling_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type **new_target)
Definition unithand.c:6538
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2722
bool unit_move(struct unit *punit, struct tile *pdesttile, int move_cost, struct unit *embark_to, bool find_embark_target, bool conquer_city_allowed, bool conquer_extras_allowed, bool enter_hut, bool frighten_hut)
Definition unittools.c:3918
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
bool utype_is_moved_to_tgt_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1249
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1587
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1484
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:190
#define utype_class(_t_)
Definition unittype.h:749
#define utype_fuel(ptype)
Definition unittype.h:839