[freeciv-ai] (PR#4026) Advanced rampage.
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
This is the second version of the "advanced rampage" patch. Main features:
* instead of looking only at adjacent tiles, it will look at all tiles
reachable within one turn.
* if a unit doesn't want to move from where it is, but still wants to
attack adjacent, it still can do by a proper choice of the thresholds.
* I put in a simple path-executing function. It might grow into
something big, when we need to execute long paths, but right now what it
does is sufficient.
The patch can be tested with armour-landed.sav.gz supplied by Pille in
(PR#3646).
Please comment on the patch. I will start committing it peacemeal soon
(I'll separate fixes to PF, stack_cost, and possibly path_execute).
G.
diff -ur -X freeciv/diff_ignore freeciv_clean/ai/aiunit.c freeciv/ai/aiunit.c
--- freeciv_clean/ai/aiunit.c Thu Apr 17 07:31:46 2003
+++ freeciv/ai/aiunit.c Fri Apr 18 00:53:32 2003
@@ -44,6 +44,9 @@
#include "unithand.h"
#include "unittools.h"
+#include "path_finding.h"
+#include "pf_tools.h"
+
#include "advmilitary.h"
#include "aiair.h"
#include "aicity.h"
@@ -62,10 +65,14 @@
static void ai_manage_barbarian_leader(struct player *pplayer,
struct unit *leader);
+#define RAMPAGE_BETTER_THAN_PILLAGE 2
+#define RAMPAGE_HUT_OR_BETTER 99998
+#define RAMPAGE_ONLY_FREE_CITY 99999
+static bool ai_military_rampage(struct unit *punit, int thresh_adj,
+ int thresh_move);
static void ai_military_findjob(struct player *pplayer,struct unit *punit);
static void ai_military_gohome(struct player *pplayer,struct unit *punit);
static void ai_military_attack(struct player *pplayer,struct unit *punit);
-static bool ai_military_rampage(struct unit *punit, int threshold);
static int unit_move_turns(struct unit *punit, int x, int y);
static bool unit_role_defender(Unit_Type_id type);
@@ -1001,181 +1008,232 @@
}
/*************************************************************************
-This function looks at tiles adjacent to the unit in order to find something
-to kill or explore. It prefers tiles in the following order:
-
-Returns value of the victim which has been chosen:
+ This function appraises the location (x, y) for a quick hit-n-run operation.
-99999 means empty (undefended) city
-99998 means hut
-2..99997 means value of enemy unit weaker than our unit
-1 means barbarians wanting to pillage
-0 means nothing found or error
--2*MORT*TRADE_WEIGHTING
- means nothing found and punit causing unhappiness
+ Returns value as follows:
-If value <= 0 is returned, (dest_x, dest_y) is set to actual punit's position.
+ -99999 means undefended enemy city
+ -99998 means hut
+ 2..99997 is value of enemy unit weaker than our unit
+ -1 means barbarians wanting to pillage
+ 0 means nothing found or error
+ Here the minus indicates that you need to enter thetarget tile (as
+ opposed to attacking it which leaves you where you are).
**************************************************************************/
-static int ai_military_findvictim(struct unit *punit, int *dest_x, int *dest_y)
+static int ai_rampage_want(struct unit *punit, int x, int y)
{
struct player *pplayer = unit_owner(punit);
- int bellig = unit_belligerence_primitive(punit);
- int x = punit->x, y = punit->y;
- int best = 0;
- int stack_size = unit_list_size(&(map_get_tile(punit->x, punit->y)->units));
+ struct unit *pdef = get_defender(punit, x, y);
CHECK_UNIT(punit);
-
- *dest_y = y;
- *dest_x = x;
-
- /* Ferryboats with passengers do not attack. */
- if (punit->ai.passenger > 0) {
- return 0;
- }
-
- if (punit->unhappiness > 0) {
- /* When we're causing unhappiness, we'll set best even lower,
- * so that we will take even targets which we would ignore otherwise
- * (in other words -- we're going to commit suicide). */
- best = - 2 * MORT * TRADE_WEIGHTING;
- }
-
- adjc_iterate(x, y, x1, y1) {
- /* Macro to set the tile with our target as the best (with value new_best)
*/
-#define SET_BEST(new_best) \
- do { best = (new_best); *dest_x = x1; *dest_y = y1; } while (FALSE)
-
- struct unit *pdef = get_defender(punit, x1, y1);
+
+ if (pdef) {
- if (pdef) {
- struct unit *patt = get_attacker(punit, x1, y1);
-
- if (!can_unit_attack_tile(punit, x1, y1)) {
- continue;
+ if (!can_unit_attack_tile(punit, x, y)) {
+ return 0;
+ }
+
+ {
+ /* See description of kill_desire() about these variables. */
+ int bellig = unit_belligerence_primitive(punit);
+ int vuln = unit_vulnerability(punit, pdef);
+ int attack = reinforcements_value(punit, pdef->x, pdef->y) + bellig;
+ int benefit = unit_type(pdef)->build_cost;
+ int loss = unit_type(punit)->build_cost;
+
+ attack *= attack;
+
+ /* If the victim is in the city, we increase the benefit and correct
+ * it with our health because there may be more units in the city
+ * stacked, and we won't destroy them all at once, so in the next
+ * turn they may attack us. So we shouldn't send already injured
+ * units to useless suicide. */
+ if (map_get_city(x, y)) {
+ /* A WAG for the city value */
+ benefit += unit_value(get_role_unit(F_CITIES, 0));
+ benefit = (benefit * punit->hp) / unit_type(punit)->hp;
}
-
- /* If we are in the city, let's deeply consider defending it - however,
- * horsemen in city refused to attack phalanx just outside that was
- * bodyguarding catapult; thus, we get the best attacker on the tile (x1,
- * y1) as well, for the case when there are multiple different units on
- * the tile (x1, y1). Thus we force punit to attack a stack of units if
- * they're endangering punit seriously, even if they aren't that weak. */
- /* FIXME: The get_total_defense_power(pdef, punit) should probably use
- * patt rather than pdef. There also ought to be a better metric for
- * determining this. */
- if (patt
- && map_get_city(x, y)
- && get_total_defense_power(pdef, punit) *
- get_total_defense_power(punit, pdef) >=
- get_total_attack_power(patt, punit) *
- get_total_attack_power(punit, pdef)
- && stack_size < 2
- && get_total_attack_power(patt, punit) > 0) {
- freelog(LOG_DEBUG, "%s's %s defending %s from %s's %s at (%d, %d)",
- pplayer->name, unit_type(punit)->name, map_get_city(x,
y)->name,
- unit_owner(pdef)->name, unit_type(pdef)->name, punit->x,
punit->y);
- } else {
- /* See description of kill_desire() about this variables. */
- int vuln = unit_vulnerability(punit, pdef);
- int attack = reinforcements_value(punit, pdef->x, pdef->y) + bellig;
- int benefit = unit_type(pdef)->build_cost;
- int loss = unit_type(punit)->build_cost;
+
+ /* If we have non-zero belligerence... */
+ if (bellig > 0 && is_my_turn(punit, pdef)) {
+ int desire;
- attack *= attack;
+ /* FIXME? Why we don't use stack_size as victim_count? --pasky */
- /* If the victim is in the city, we increase the benefit and correct
- * it with our health because there may be more units in the city
- * stacked, and we won't destroy them all at once, so in the next
- * turn they may attack us. So we shouldn't send already injured
- * units to useless suicide. */
- if (map_get_city(x1, y1)) {
- benefit += unit_value(get_role_unit(F_CITIES, 0));
- benefit = (benefit * punit->hp) / unit_type(punit)->hp;
- }
+ desire = kill_desire(benefit, attack, loss, vuln, 1);
- /* If we have non-zero belligerence... */
- if (attack > 0 && is_my_turn(punit, pdef)) {
- int desire;
-
- /* FIXME? Why we don't use stack_size as victim_count? --pasky */
-
- desire = kill_desire(benefit, attack, loss, vuln, 1);
-
- /* No need to amortize! We're doing it in one-turn horizon. */
-
- if (desire > best && ai_fuzzy(pplayer, TRUE)) {
- freelog(LOG_DEBUG, "Better than %d is %d (%s)",
- best, desire, unit_type(pdef)->name);
- SET_BEST(desire);
- } else {
- freelog(LOG_DEBUG, "NOT better than %d is %d (%s)",
- best, desire, unit_type(pdef)->name);
- }
- }
+ /* No need to amortize! We're doing it in one-turn horizon. */
+ return desire;
}
+ }
+
+ } else {
+ struct city *pcity = map_get_city(x, y);
+
+ /* No defender... */
+
+ /* ...and free foreign city waiting for us. Who would resist! */
+ if (pcity && pplayers_at_war(pplayer, city_owner(pcity))
+ && COULD_OCCUPY(punit)) {
- } else {
- struct city *pcity = map_get_city(x1, y1);
+ return -RAMPAGE_ONLY_FREE_CITY;
+ }
+
+ /* ...or tiny pleasant hut here! */
+ if (map_has_special(x, y, S_HUT) && !is_barbarian(pplayer)) {
- /* No defender... */
-
- /* ...and free foreign city waiting for us. Who would resist! */
- if (pcity && pplayers_at_war(pplayer, city_owner(pcity))
- && could_unit_move_to_tile(punit, x1, y1) != 0
- && COULD_OCCUPY(punit)
- && !is_ocean(map_get_terrain(punit->x, punit->y))) {
- SET_BEST(99999);
- continue;
- }
+ return -RAMPAGE_HUT_OR_BETTER;
+ }
+
+ /* If we have nothing to do, we can at least pillage something, hmm? */
+ if (is_land_barbarian(pplayer)
+ && get_tile_infrastructure_set(map_get_tile(x, y)) != S_NO_SPECIAL) {
+ return -(RAMPAGE_BETTER_THAN_PILLAGE - 1);
+ }
+ }
+
+ return 0;
+}
- /* ...or tiny pleasant hut here! */
- if (map_has_special(x1, y1, S_HUT) && best < 99999
- && could_unit_move_to_tile(punit, x1, y1) != 0
- && !is_barbarian(unit_owner(punit))
- && punit->ai.ai_role != AIUNIT_ESCORT
- && punit->ai.charge == BODYGUARD_NONE /* Above line doesn't seem to
work. :( */
- && punit->ai.ai_role != AIUNIT_DEFEND_HOME) {
- SET_BEST(99998);
- continue;
- }
-
- /* If we have nothing to do, we can at least pillage something, hmm? */
- if (is_land_barbarian(pplayer) && best == 0
- && get_tile_infrastructure_set(map_get_tile(x1, y1)) != S_NO_SPECIAL
- && could_unit_move_to_tile(punit, x1, y1) != 0) {
- SET_BEST(1);
- continue;
- }
+/*************************************************************************
+ Look for worthy targets within a one-turn horizon.
+*************************************************************************/
+static bool find_rampage_target(struct unit *punit,
+ int thresh_adj, int thresh_move,
+ int *x, int *y,
+ struct pf_path **path)
+{
+ struct pf_map *map;
+ struct pf_parameter parameter;
+ int max_want = 0;
+ struct player *pplayer = unit_owner(punit);
+
+ pft_fill_default_parameter(¶meter);
+ pft_fill_unit_attack_param(¶meter, punit);
+
+ map = pf_create_map(¶meter);
+ while (pf_next(map)) {
+ struct pf_position pos;
+ int want;
+ bool move_needed;
+ int thresh;
+
+ pf_next_get_position(map, &pos);
+
+ if (pos.total_MC > punit->moves_left) {
+ /* This is too far */
+ break;
}
-#undef SET_BEST
- } adjc_iterate_end;
- return best;
+ if (ai_handicap(pplayer, H_TARGETS)
+ && !map_get_known_and_seen(pos.x, pos.y, pplayer)) {
+ /* The target is under fog of war */
+ continue;
+ }
+
+ want = ai_rampage_want(punit, pos.x, pos.y);
+
+ /* Negative want means move needed even though the tiles are adjacent */
+ move_needed = (!is_tiles_adjacent(punit->x, punit->y, pos.x, pos.y)
+ || want < 0);
+ /* Select the relevant threshold */
+ thresh = (move_needed ? thresh_move : thresh_adj);
+ want = (want < 0 ? -want : want);
+
+ if (want > max_want && want > thresh) {
+ /* The new want exceeds both the previous maximum
+ * and the relevant threshold, so it's worth recording */
+ max_want = want;
+ *x = pos.x;
+ *y = pos.y;
+ }
+ }
+
+ if (max_want > 0) {
+ /* We found something */
+ *path = pf_get_path(map, *x, *y);
+ assert(*path);
+ }
+
+ pf_destroy_map(map);
+
+ return (max_want > 0);
+}
+
+/*************************************************************************
+ This is a function to execute paths returned by the path-finding engine.
+ It is analogous to goto_route_execute,only much simpler.
+*************************************************************************/
+static bool ai_unit_execute_path(struct unit *punit, struct pf_path *path)
+{
+ int i;
+ int sanity = punit->id;
+
+ handle_unit_activity_request(punit, ACTIVITY_IDLE);
+ pf_print_path(LOG_NORMAL, path);
+
+ /* We start with i = 1 for i = 0 is our present position */
+ for (i = 1; i < path->length; i++) {
+ struct packet_move_unit pmove;
+
+ pmove.x = path->positions[i].x;
+ pmove.y = path->positions[i].y;
+ pmove.unid = punit->id;
+ handle_move_unit(unit_owner(punit), &pmove);
+
+ if (!find_unit_by_id(sanity)) {
+ /* Died... */
+ return FALSE;
+ }
+
+ if (!same_pos(punit->x, punit->y, pmove.x, pmove.y)) {
+ /* Stopped (or maybe fought) */
+ return TRUE;
+ }
+ }
+
+ return TRUE;
}
/*************************************************************************
- Find and kill anything adjacent to us that we don't like with a
- given threshold until we have run out of juicy targets or movement.
- Wraps ai_military_findvictim().
+ Find and kill anything reachable within this turn and worth more than
+ the relevant of the given thresholds until we have run out of juicy
+ targets or movement. The first threshold is for attacking which will
+ leave us where we stand (attacking adjacent units), the second is for
+ attacking distant (butwithin reach) targets.
+
+ For example, if unit is a bodyguard on duty, it should call
+ ai_military_rampage(punit, 100, RAMPAGE_ONLY_FREE_CITY)
+ meaning "we will move _only_ to pick up a free city but we are happy to
+ attack adjacent squares as long as they are worthy of it".
+
Returns TRUE if survived the rampage session.
**************************************************************************/
-static bool ai_military_rampage(struct unit *punit, int threshold)
+static bool ai_military_rampage(struct unit *punit, int thresh_adj,
+ int thresh_move)
{
int x, y;
int count = punit->moves_left + 1; /* break any infinite loops */
-
+ struct pf_path *path = NULL;
+
CHECK_UNIT(punit);
- while (punit->moves_left > 0 && count-- > 0
- && ai_military_findvictim(punit, &x, &y) >= threshold) {
- if (!ai_unit_attack(punit, x, y)) {
+ while (count-- > 0 && punit->moves_left > 0
+ && find_rampage_target(punit, thresh_adj, thresh_move, &x, &y,
&path)) {
+ if (!ai_unit_execute_path(punit, path)) {
/* Died */
- return FALSE;
+ count = -1;
}
+ pf_destroy_path(path);
+ path = NULL;
}
- assert(count >= 0);
- return TRUE;
+
+ if (path) {
+ pf_destroy_path(path);
+ path = NULL;
+ }
+
+ return (count >= 0);
}
/*************************************************************************
@@ -1220,8 +1278,11 @@
ai_unit_new_role(punit, AIUNIT_NONE, -1, -1);
}
} else {
- /* I had these guys set to just fortify, which is so dumb. -- Syela */
- (void) ai_military_rampage(punit, 40 * SHIELD_WEIGHTING);
+ /* I had these guys set to just fortify, which is so dumb. -- Syela
+ * Instead we can attack adjacent units and maybe even pick up some free
+ * cities! */
+ (void) ai_military_rampage(punit, 40 * SHIELD_WEIGHTING,
+ RAMPAGE_ONLY_FREE_CITY);
}
}
@@ -1742,7 +1803,9 @@
freelog(LOG_DEBUG, "INHOUSE. GOTO AI_NONE(%d)", punit->id);
ai_unit_new_role(punit, AIUNIT_NONE, -1, -1);
/* aggro defense goes here -- Syela */
- (void) ai_military_rampage(punit, 2); /* 2 is better than pillage */
+ /* Attack just about anything */
+ (void) ai_military_rampage(punit, RAMPAGE_BETTER_THAN_PILLAGE,
+ RAMPAGE_BETTER_THAN_PILLAGE);
} else {
UNIT_LOG(LOG_DEBUG, punit, "GOHOME");
(void) ai_unit_goto(punit, pcity->x, pcity->y);
@@ -2308,7 +2371,7 @@
/*************************************************************************
This does the attack until we have used up all our movement, unless we
- should safeguard a city. First we rampage on adjacent tiles, then we go
+ should safeguard a city. First we rampage nearby, then we go
looking for trouble elsewhere. If there is nothing to kill, sailing units
go home, others explore while barbs go berserk.
**************************************************************************/
@@ -2323,8 +2386,9 @@
/* Main attack loop */
do {
- /* First find easy adjacent enemies; 2 is better than pillage */
- if (!ai_military_rampage(punit, 2)) {
+ /* First find easy nearby enemies, anything better than pillage goes */
+ if (!ai_military_rampage(punit, RAMPAGE_BETTER_THAN_PILLAGE,
+ RAMPAGE_BETTER_THAN_PILLAGE)) {
return; /* we died */
}
@@ -2659,8 +2723,9 @@
if (pcity) {
/* rest in city until the hitpoints are recovered, but attempt
- to protect city from attack */
- if (ai_military_rampage(punit, 2)) {
+ to protect city from attack (and be opportunistic too)*/
+ if (ai_military_rampage(punit, RAMPAGE_BETTER_THAN_PILLAGE,
+ RAMPAGE_ONLY_FREE_CITY)) {
freelog(LOG_DEBUG, "%s's %s(%d) at (%d, %d) recovering hit points.",
pplayer->name, unit_type(punit)->name, punit->id, punit->x,
punit->y);
@@ -2669,8 +2734,9 @@
}
} else {
/* goto to nearest city to recover hit points */
- /* just before, check to see if we can occupy at enemy city undefended */
- if (!ai_military_rampage(punit, 99999)) {
+ /* just before, check to see if we can occupy an undefended enemy city */
+ if (!ai_military_rampage(punit, RAMPAGE_ONLY_FREE_CITY,
+ RAMPAGE_ONLY_FREE_CITY)) {
return; /* oops, we died */
}
diff -ur -X freeciv/diff_ignore freeciv_clean/common/aicore/path_finding.c
freeciv/common/aicore/path_finding.c
--- freeciv_clean/common/aicore/path_finding.c Fri Mar 21 20:49:27 2003
+++ freeciv/common/aicore/path_finding.c Thu Apr 17 13:03:17 2003
@@ -208,9 +208,12 @@
bool my_zoc = (tile->city || tile->terrain == T_OCEAN
|| is_my_zoc(params->owner, x, y));
bool allied = (is_allied_unit_tile(tile, params->owner) != NULL);
+ bool enemy = (is_enemy_unit_tile(tile, params->owner) != NULL);
/* if my zoc 2 else if allied 1 else 0 */
- node->zoc_number = (my_zoc ? 2 : (allied ? 1 : 0));
+ /* Essentially, enemy tile is like allied tile, we should be allowed
+ * to go there (attack), but not to leave, necessarily */
+ node->zoc_number = (my_zoc ? 2 : ((allied || enemy) ? 1 : 0));
}
/* Evaluate the extra cost of the destination */
@@ -574,6 +577,11 @@
/* pf_fill_position doesn't set direction */
path->positions[i].dir_to_next_pos = dir_next;
+ if (i == 0) {
+ /* That's it */
+ break;
+ }
+
dir_next = node->dir_to_here;
/* Step further back */
@@ -651,8 +659,10 @@
************************************************************************/
void pf_destroy_path(struct pf_path *path)
{
- free(path->positions);
- free(path);
+ if (path) {
+ free(path->positions);
+ free(path);
+ }
}
diff -ur -X freeciv/diff_ignore freeciv_clean/common/aicore/pf_tools.c
freeciv/common/aicore/pf_tools.c
--- freeciv_clean/common/aicore/pf_tools.c Tue Mar 11 17:59:26 2003
+++ freeciv/common/aicore/pf_tools.c Thu Apr 17 13:03:17 2003
@@ -55,9 +55,30 @@
return PF_IMPOSSIBLE_MC;
}
+/**********************************************************************
+ Sea attack is the same as overlap (consider bombardment) but we don't
+ want to pass through enemy tiles.
+**********************************************************************/
+static int sea_attack_move(int x, int y, enum direction8 dir,
+ int x1, int y1, struct pf_parameter *param)
+{
+ struct tile *src_tile = map_get_tile(x, y);
+
+ if (src_tile->terrain == T_OCEAN) {
+ if (is_non_allied_unit_tile(src_tile, param->owner)) {
+ return PF_IMPOSSIBLE_MC;
+ }
+ return SINGLE_MOVE;
+ } else if (is_allied_city_tile(map_get_tile(x, y), param->owner)
+ && map_get_terrain(x1, y1) == T_OCEAN) {
+ return SINGLE_MOVE;
+ }
+
+ return PF_IMPOSSIBLE_MC;
+}
+
/************************************************************
LAND_MOVE cost function for a unit
- Must put owner into *data.
************************************************************/
static int normal_move_unit(int x, int y, enum direction8 dir,
int x1, int y1, struct pf_parameter *param)
@@ -81,6 +102,55 @@
return move_cost;
}
+/*******************************************************************
+ LAND_MOVE cost function for a unit, but taking into account
+ possibilities of attacking.
+*******************************************************************/
+static int land_attack_move(int x, int y, enum direction8 dir,
+ int x1, int y1, struct pf_parameter *param)
+{
+ struct tile *src_tile = map_get_tile(x, y);
+ struct tile *tgt_tile = map_get_tile(x1, y1);
+ int move_cost;
+
+ if (tgt_tile->terrain == T_OCEAN) {
+
+ /* Any-to-Sea */
+ if (ground_unit_transporter_capacity(x1, y1, param->owner) > 0) {
+ move_cost = SINGLE_MOVE;
+ } else {
+ move_cost = PF_IMPOSSIBLE_MC;
+ }
+ } else if (src_tile->terrain == T_OCEAN) {
+
+ /* Sea-to-Land. TODO: Marines support */
+ if (!is_non_allied_unit_tile(tgt_tile, param->owner)) {
+ move_cost
+ = get_tile_type(tgt_tile->terrain)->movement_cost * SINGLE_MOVE;
+ } else {
+ move_cost = PF_IMPOSSIBLE_MC;
+ }
+ } else {
+
+ /* Land-to-Land */
+ if (is_non_allied_unit_tile(src_tile, param->owner)) {
+ /* Cannot pass through defended tiles */
+ move_cost = PF_IMPOSSIBLE_MC;
+ } else if(is_non_allied_unit_tile(tgt_tile, param->owner)) {
+
+ /* TODO: Intelligent checking */
+ /* Attack! */
+ move_cost = SINGLE_MOVE;
+ } else {
+ /* Normal move */
+ move_cost = src_tile->move_cost[dir];
+ }
+ }
+
+ return move_cost;
+}
+
+
/************************************************************
A cost function for a land unit, which allows going into
the ocean (with moves costing SINGLE_MOVE). It is
@@ -315,11 +385,13 @@
break;
case SEA_MOVING:
parameter->get_MC = sea_overlap_move;
+ break;
default:
die("Unsupported move_type");
}
parameter->zoc_used = FALSE;
+ parameter->omniscience = TRUE;
if (unit_flag(punit, F_TRIREME)
&& base_trireme_loss_pct(unit_owner(punit)) > 0) {
@@ -330,6 +402,41 @@
}
/**********************************************************************
+ Consider attacking and non-attacking possibilities properly
+**********************************************************************/
+void pft_fill_unit_attack_param(struct pf_parameter *parameter,
+ struct unit *punit)
+{
+ parameter->turn_mode = TM_CAPPED;
+ parameter->get_TB = NULL;
+ parameter->get_EC = NULL;
+
+ parameter->start_x = punit->x;
+ parameter->start_y = punit->y;
+ parameter->moves_left_initially = punit->moves_left;
+ parameter->move_rate = unit_move_rate(punit);
+ parameter->owner = unit_owner(punit);
+
+ switch (unit_type(punit)->move_type) {
+ case LAND_MOVING:
+ parameter->get_MC = land_attack_move;
+ break;
+ case SEA_MOVING:
+ parameter->get_MC = sea_attack_move;
+ break;
+ default:
+ die("Unsupported move_type");
+ }
+
+ parameter->zoc_used = (unit_type(punit)->move_type == LAND_MOVING
+ && !unit_flag(punit, F_IGZOC));
+ parameter->omniscience = TRUE;
+
+ /* It is too complicated to work with danger here */
+ parameter->is_pos_dangerous = NULL;
+}
+
+/**********************************************************************
Fill general use parameters to defaults
***********************************************************************/
void pft_fill_default_parameter(struct pf_parameter *parameter)
diff -ur -X freeciv/diff_ignore freeciv_clean/common/aicore/pf_tools.h
freeciv/common/aicore/pf_tools.h
--- freeciv_clean/common/aicore/pf_tools.h Tue Mar 11 17:59:26 2003
+++ freeciv/common/aicore/pf_tools.h Thu Apr 17 13:03:17 2003
@@ -20,6 +20,8 @@
struct unit *punit);
void pft_fill_unit_overlap_param(struct pf_parameter *parameter,
struct unit *punit);
+void pft_fill_unit_attack_param(struct pf_parameter *parameter,
+ struct unit *punit);
/*
* Below iterator is mostly for use by AI, iterates through all positions
Only in freeciv/: core.18662
Only in freeciv_clean/: saves
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freeciv-ai] (PR#4026) Advanced rampage.,
Gregory Berkolaiko <=
|
|