Freeciv-3.3
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
59 punit->goto_tile = ptile;
62
63 if (alive) {
64 if (activity != ACTIVITY_GOTO) {
65 /* Only go via ACTIVITY_IDLE if we are actually changing the activity */
67 send_unit_info(NULL, punit); /* FIXME: probably duplicate */
69 activity_default_action(activity));
70 }
71 punit->goto_tile = old_tile; /* May be NULL. */
73 }
74
75 return alive;
76}
77
78
79/**********************************************************************/
86bool adv_unit_execute_path(struct unit *punit, struct pf_path *path)
87{
88 const bool is_plr_ai = is_ai(unit_owner(punit));
89 int i;
90
91 /* We start with i = 1 for i = 0 is our present position */
92 for (i = 1; i < path->length; i++) {
93 struct tile *ptile = path->positions[i].tile;
94 int id = punit->id;
95
96 if (same_pos(unit_tile(punit), ptile)) {
97#ifdef PF_WAIT_DEBUG
99#if PF_WAIT_DEBUG & 1
101#if PF_WAIT_DEBUG & (2 | 4)
102 ||
103#endif
104#endif
105#if PF_WAIT_DEBUG & 2
107#if PF_WAIT_DEBUG & 4
108 ||
109#endif
110#endif
111#if PF_WAIT_DEBUG & 4
113#endif
114 , "%s waits at %d,%d for no visible profit",
115 unit_rule_name(punit), TILE_XY(ptile));
116#endif
117 UNIT_LOG(LOG_DEBUG, punit, "execute_path: waiting this turn");
118 return TRUE;
119 }
120
121 /* We use ai_unit_move() for everything but the last step
122 * of the way so that we abort if unexpected opposition
123 * shows up. Any enemy on the target tile is expected to
124 * be our target and any attack there intentional.
125 * However, do not annoy human players by automatically attacking
126 * using units temporarily under AI control (such as auto-explorers)
127 */
128
129 if (is_plr_ai) {
131 } else {
132 (void) adv_unit_move(punit, ptile);
133 }
134 if (!game_unit_by_number(id)) {
135 /* Died... */
136 return FALSE;
137 }
138
139 if (!same_pos(unit_tile(punit), ptile) || punit->moves_left <= 0) {
140 /* Stopped (or maybe fought) or ran out of moves */
141 return TRUE;
142 }
143 }
144
145 return TRUE;
146}
147
148/**********************************************************************/
156static bool adv_unit_move(struct unit *punit, struct tile *ptile)
157{
158 struct action *paction;
159 struct player *pplayer = unit_owner(punit);
160 struct unit *ptrans = NULL;
161 const struct civ_map *nmap = &(wld.map);
162
163 /* If enemy, stop and give a chance for the human player to
164 handle this case */
165 if (is_enemy_unit_tile(ptile, pplayer)
166 || is_enemy_city_tile(ptile, pplayer)) {
167 UNIT_LOG(LOG_DEBUG, punit, "movement halted due to enemy presence");
168 return FALSE;
169 }
170
171 /* Select move kind. */
173 && ((ptrans = transporter_for_unit_at(punit, ptile)))
175 punit, ptrans)) {
176 /* "Transport Embark". */
178 } else if (!can_unit_survive_at_tile(nmap, punit, ptile)
179 && ptrans != NULL
181 punit, ptrans)) {
182 /* "Transport Embark 2". */
184 } else if (!can_unit_survive_at_tile(nmap, punit, ptile)
185 && ptrans != NULL
187 punit, ptrans)) {
188 /* "Transport Embark 3". */
190 } else if (!can_unit_survive_at_tile(nmap, punit, ptile)
191 && ptrans != NULL
193 punit, ptrans)) {
194 /* "Transport Embark 4". */
197 punit, ptile, NULL)) {
198 /* "Transport Disembark". */
201 punit, ptile, NULL)) {
202 /* "Transport Disembark 2". */
205 punit, ptile, NULL)) {
206 /* "Transport Disembark 3". */
209 punit, ptile, NULL)) {
210 /* "Transport Disembark 4". */
213 punit, ptile, NULL)) {
214 /* "Enter Hut". */
217 punit, ptile, NULL)) {
218 /* "Enter Hut 2". */
221 punit, ptile, NULL)) {
222 /* "Enter Hut 3". */
225 punit, ptile, NULL)) {
226 /* "Enter Hut 4". */
229 punit, ptile, NULL)) {
230 /* "Frighten Hut". */
233 punit, ptile, NULL)) {
234 /* "Frighten Hut 2". */
237 punit, ptile, NULL)) {
238 /* "Frighten Hut 3". */
241 punit, ptile, NULL)) {
242 /* "Frighten Hut 4". */
245 punit, ptile, NULL)) {
246 /* "Unit Move". */
249 punit, ptile, NULL)) {
250 /* "Unit Move 2". */
252 } else {
253 /* "Unit Move 3". */
255 }
256
257 /* Try not to end move next to an enemy if we can avoid it by waiting */
260 /* The unit will have to move it self rather than being moved. */
261 int mcost = map_move_cost_unit(nmap, punit, ptile);
262
263 if (paction) {
264 struct tile *from_tile;
265
266 /* Ugly hack to understand the OnNativeTile unit state requirements
267 * used in the Action_Success_Actor_Move_Cost effect. */
271 punit->tile = ptile;
272
274
276 }
277
278 if (punit->moves_left <= mcost
279 && unit_move_rate(punit) > mcost
280 && adv_danger_at(punit, ptile)
283 "ending move early to stay out of trouble");
284 return FALSE;
285 }
286 }
287
288 /* Go */
290 /* Move */
291 /* TODO: Differentiate (server side AI) player from server side agent
292 * working for (possibly AI) player by using ACT_REQ_PLAYER and
293 * ACT_REQ_SS_AGENT */
294 if (paction != nullptr && ptrans != nullptr
296 /* "Transport Embark". */
298 0, "", action_number(paction));
299 } else if (paction
308 /* "Transport Disembark", "Transport Disembark 2", "Enter Hut",
309 * "Frighten Hut" or "Unit Move". */
311 0, "", action_number(paction));
312 }
313
314 return TRUE;
315}
316
317/**********************************************************************/
324static bool adv_could_be_my_zoc(struct unit *punit, struct tile *ptile)
325{
326 struct tile *utile = unit_tile(punit);
327 struct player *owner;
328 struct civ_map *cmap = &(wld.map);
330
331 if (same_pos(ptile, utile)) {
332 return FALSE; /* Can't be my zoc */
333 }
334
336 if (is_tiles_adjacent(ptile, utile)
338 return FALSE;
339 }
340
341 adjc_iterate(cmap, ptile, atile) {
344 return FALSE;
345 }
347
348 return TRUE;
349}
350
351/**********************************************************************/
359int adv_could_unit_move_to_tile(struct unit *punit, struct tile *dest_tile)
360{
364 TRUE, NULL, FALSE);
365
366 switch (reason) {
367 case MR_OK:
368 return 1;
369
370 case MR_ZOC:
372 return -1;
373 }
374 break;
375
376 default:
377 break;
378 };
379 return 0;
380}
381
382/**********************************************************************/
385int adv_unittype_att_rating(const struct unit_type *punittype, int veteran,
386 int moves_left, int hp)
387{
388 return base_get_attack_power(punittype, veteran, moves_left) * hp
389 * punittype->firepower / POWER_DIVIDER;
390}
391
392/**********************************************************************/
401
402/**********************************************************************/
411
412/**********************************************************************/
416{
418
419 return v * v;
420}
421
422/**********************************************************************/
425bool adv_danger_at(struct unit *punit, struct tile *ptile)
426{
427 int a = 0, d, db;
428 struct player *pplayer = unit_owner(punit);
429 struct city *pcity = tile_city(ptile);
431 int extras_bonus = 0;
432 struct player *owner = unit_owner(punit);
433
434 /* Give AI code possibility to decide itself */
435 CALL_PLR_AI_FUNC(consider_tile_dangerous, owner, ptile, punit, &dc);
436 if (dc == OVERRIDE_TRUE) {
437 return TRUE;
438 } else if (dc == OVERRIDE_FALSE) {
439 return FALSE;
440 }
441
443 && !is_non_allied_unit_tile(ptile, pplayer,
445 /* We will be safe in a friendly city */
446 return FALSE;
447 }
448
449 /* Calculate how well we can defend at (x,y) */
450 db = 10 + tile_terrain(ptile)->defense_bonus / 10;
452 db += (db * extras_bonus) / 100;
454
455 adjc_iterate(&(wld.map), ptile, ptile1) {
457 /* We cannot see danger at (ptile1) => assume there is none */
458 continue;
459 }
463 == ATT_OK)
465 == ATT_OK)) {
467 if ((a * a * 10) >= d) {
468 /* The enemies combined strength is too big! */
469 return TRUE;
470 }
471 }
474
475 return FALSE; /* As good a quick'n'dirty should be -- Syela */
476}
477
478/**********************************************************************/
481static int stack_value(const struct tile *ptile,
482 const struct player *pplayer)
483{
484 int cost = 0;
485
486 if (is_stack_vulnerable(ptile)) {
487 unit_list_iterate(ptile->units, punit) {
488 if (unit_owner(punit) == pplayer) {
490 }
492 }
493
494 return cost;
495}
496
497/**********************************************************************/
507static double chance_killed_at(const struct tile *ptile,
508 struct adv_risk_cost *risk_cost,
509 const struct pf_parameter *param)
510{
511 double db;
512 int extras_bonus = 0;
513 /* Compute the basic probability */
514 /* WAG */
515 /* In the early stages of a typical game, ferries
516 * are effectively invulnerable (not until Frigates set sail),
517 * so we make seas appear safer.
518 * If we don't do this, the amphibious movement code has too strong a
519 * desire to minimise the length of the path,
520 * leading to poor choice for landing beaches */
521 double p = is_ocean_tile(ptile)? 0.05: 0.15;
522
523 /* If we are on defensive terrain, we are more likely to survive */
524 db = 10 + tile_terrain(ptile)->defense_bonus / 10;
526 utype_class(param->utype));
527 db += (extras_bonus) / 100;
528 p *= 10.0 / db;
529
530 return p;
531}
532
533/**********************************************************************/
548static unsigned stack_risk(const struct tile *ptile,
549 struct adv_risk_cost *risk_cost,
550 const struct pf_parameter *param)
551{
552 double risk = 0;
553 /* Compute the risk of destruction, assuming we will stop at this tile */
554 const double value = risk_cost->base_value
555 + stack_value(ptile, param->owner);
556 const double p_killed = chance_killed_at(ptile, risk_cost, param);
557 double danger = value * p_killed;
558
559 /* Adjust for the fact that we might not stop at this tile,
560 * and for our fearfulness */
561 risk += danger * risk_cost->fearfulness;
562
563 /* Adjust for the risk that we might become stuck (for an indefinite period)
564 * if we enter or try to enter the tile. */
565 if (risk_cost->enemy_zoc_cost != 0
566 && (is_non_allied_city_tile(ptile, param->owner)
567 || !is_plr_zoc_srv(param->owner, ptile, param->map)
568 || is_non_allied_unit_tile(ptile, param->owner,
570 /* We could become stuck. */
571 risk += risk_cost->enemy_zoc_cost;
572 }
573
574 return risk;
575}
576
577/**********************************************************************/
584static unsigned prefer_short_stacks(const struct tile *ptile,
585 enum known_type known,
586 const struct pf_parameter *param)
587{
588 return stack_risk(ptile, (struct adv_risk_cost *)param->data, param);
589}
590
591/**********************************************************************/
595void adv_avoid_risks(struct pf_parameter *parameter,
596 struct adv_risk_cost *risk_cost,
597 struct unit *punit,
598 const double fearfulness)
599{
600 /* If we stay a short time on each tile, the danger of each individual tile
601 * is reduced. If we do not do this,
602 * we will not favour longer but faster routs. */
603 const double linger_fraction = (double)SINGLE_MOVE / parameter->move_rate;
604
605 parameter->data = risk_cost;
606 parameter->get_EC = prefer_short_stacks;
608 risk_cost->fearfulness = fearfulness * linger_fraction;
609
610 risk_cost->enemy_zoc_cost = PF_TURN_FACTOR * 20;
611}
int action_number(const struct action *action)
Definition actions.c:1208
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:3332
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:3168
static struct action * action_by_number(action_id act_id)
Definition actions.h:396
#define action_has_result(_act_, _res_)
Definition actions.h:180
#define ACTION_NONE
Definition actions.h:55
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:415
static int stack_value(const struct tile *ptile, const struct player *pplayer)
Definition advgoto.c:481
int adv_unit_def_rating_basic(const struct unit *punit)
Definition advgoto.c:406
static unsigned prefer_short_stacks(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Definition advgoto.c:584
static unsigned stack_risk(const struct tile *ptile, struct adv_risk_cost *risk_cost, const struct pf_parameter *param)
Definition advgoto.c:548
bool adv_danger_at(struct unit *punit, struct tile *ptile)
Definition advgoto.c:425
static bool adv_unit_move(struct unit *punit, struct tile *ptile)
Definition advgoto.c:156
static double chance_killed_at(const struct tile *ptile, struct adv_risk_cost *risk_cost, const struct pf_parameter *param)
Definition advgoto.c:507
int adv_unittype_att_rating(const struct unit_type *punittype, int veteran, int moves_left, int hp)
Definition advgoto.c:385
int adv_unit_att_rating(const struct unit *punit)
Definition advgoto.c:396
static bool adv_could_be_my_zoc(struct unit *punit, struct tile *ptile)
Definition advgoto.c:324
int adv_could_unit_move_to_tile(struct unit *punit, struct tile *dest_tile)
Definition advgoto.c:359
void adv_avoid_risks(struct pf_parameter *parameter, struct adv_risk_cost *risk_cost, struct unit *punit, const double fearfulness)
Definition advgoto.c:595
bool adv_unit_execute_path(struct unit *punit, struct pf_path *path)
Definition advgoto.c:86
#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:767
static bool is_enemy_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:731
#define city_owner(_pcity_)
Definition city.h:560
bool is_stack_vulnerable(const struct tile *ptile)
Definition combat.c:994
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:257
int base_get_attack_power(const struct unit_type *punittype, int veteran, int moves_left)
Definition combat.c:550
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:123
int base_get_defense_power(const struct unit *punit)
Definition combat.c:574
@ ATT_OK
Definition combat.h:35
char * incite_cost
Definition comments.c:76
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 const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
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:62
struct unit * game_unit_by_number(int id)
Definition game.c:115
struct city * owner
Definition citydlg.c:226
#define fc_assert_msg(condition, message,...)
Definition log.h:182
#define fc_assert(condition)
Definition log.h:177
@ LOG_DEBUG
Definition log.h:35
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Definition map.c:1067
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:1076
#define adjc_iterate_end
Definition map.h:430
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:425
static int map_move_cost_unit(const struct civ_map *nmap, struct unit *punit, const struct tile *ptile)
Definition map.h:290
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:925
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:629
int unit_move_rate(const struct unit *punit)
Definition movement.c:89
bool can_unit_survive_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:490
#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:1409
#define is_ai(plr)
Definition player.h:232
#define UNIT_LOG(loglevel, punit, msg,...)
Definition srv_log.h:98
Definition city.h:317
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:532
Definition unit.h:140
enum unit_activity activity
Definition unit.h:159
int moves_left
Definition unit.h:152
int id
Definition unit.h:147
int hp
Definition unit.h:153
int fuel
Definition unit.h:155
struct tile * tile
Definition unit.h:142
struct extra_type * activity_target
Definition unit.h:167
struct tile * goto_tile
Definition unit.h:157
int veteran
Definition unit.h:154
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define is_ocean_tile(ptile)
Definition terrain.h:196
#define terrain_has_flag(terr, flag)
Definition terrain.h:176
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:89
known_type
Definition tile.h:35
#define tile_terrain(_tile)
Definition tile.h:111
#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:2172
struct unit * transporter_for_unit_at(const struct unit *pcargo, const struct tile *ptile)
Definition unit.c:1959
enum gen_action activity_default_action(enum unit_activity act)
Definition unit.c:2930
bool is_plr_zoc_srv(const struct player *pplayer, const struct tile *ptile0, const struct civ_map *zmap)
Definition unit.c:1424
#define unit_tile(_pu)
Definition unit.h:404
static bool is_enemy_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:427
#define unit_owner(_pu)
Definition unit.h:403
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer, bool everyone_non_allied)
Definition unit.h:440
bool unit_activity_handling_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type **new_target, enum gen_action trigger_action)
Definition unithand.c:6735
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unithand.c:6663
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:3338
#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:2877
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:4078
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:1255
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1593
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1490
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:196
#define utype_class(_t_)
Definition unittype.h:756
#define utype_fuel(ptype)
Definition unittype.h:846
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:624