[freeciv-ai] Re: (PR#6308) Cleanup of ferry handling
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
On Sun, 28 Sep 2003, Gregory Berkolaiko wrote:
> I will attach a patch (in the next email) which cleans and rewrites two
> functions: ai_manage_ferryboat and ai_military_gothere.
And the patch.
G.
? core.11877
? eee.gz
? rrr.gz
? ttt.gz
Index: ai/aiunit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
retrieving revision 1.297
diff -u -r1.297 aiunit.c
--- ai/aiunit.c 2003/09/28 09:33:21 1.297
+++ ai/aiunit.c 2003/09/28 11:41:24
@@ -59,8 +59,10 @@
#include "aiunit.h"
+#define FERRY_WANTED -1
#define LOGLEVEL_RECOVERY LOG_DEBUG
+static void ai_manage_unit(struct player *pplayer, struct unit *punit);
static void ai_manage_military(struct player *pplayer,struct unit *punit);
static void ai_manage_caravan(struct player *pplayer, struct unit *punit);
static void ai_manage_barbarian_leader(struct player *pplayer,
@@ -1292,118 +1294,167 @@
/* What if we have a bodyguard, but don't need one? */
}
-/**************************************************************************
- Return values: FALSE if died or stuck, TRUE otherwise. (This function
- is not server-side autoattack safe.)
-**************************************************************************/
-static bool ai_military_gothere(struct player *pplayer, struct unit *punit,
- int dest_x, int dest_y)
+#define LOGLEVEL_GOTHERE LOG_NORMAL
+/****************************************************************************
+ Return values: TRUE if got to or next to our destination, FALSE otherwise.
+
+ TODO: A big one is rendez-vous points. When this is implemented, we won't
+ have to be at the coast to ask for a boat to come to us.
+****************************************************************************/
+bool ai_military_gothere(struct player *pplayer, struct unit *punit,
+ int dest_x, int dest_y)
{
- int id, x, y, boatid = 0, bx = -1, by = -1;
- struct unit *ferryboat = NULL;
- struct unit *def;
- struct tile *ptile;
- bool boat_arrived;
-
CHECK_UNIT(punit);
-
- id = punit->id; x = punit->x; y = punit->y;
- if (same_pos(dest_x, dest_y, x, y)) {
+ if (same_pos(dest_x, dest_y, punit->x, punit->y)) {
/* Nowhere to go */
- return FALSE;
- }
-
- if (is_ground_unit(punit)) {
- boatid = find_boat(pplayer, &bx, &by, 2);
- /* NB: ferryboat is set only if the boat is where we are */
- ferryboat = unit_list_find(&(map_get_tile(x, y)->units), boatid);
+ return TRUE;
}
/* See if we need a bodyguard at our destination */
+ /* FIXME: If bodyguard is _really_ necessary, don't go anywhere */
ai_gothere_bodyguard(punit, dest_x, dest_y);
-
- if (!goto_is_sane(punit, dest_x, dest_y, TRUE)
- || (ferryboat && goto_is_sane(ferryboat, dest_x, dest_y, TRUE))) {
+
+ /* If we can, we will walk, take boat only if necessary */
+ if (punit->transported_by > 0
+ || !goto_is_sane(punit, dest_x, dest_y, TRUE)) {
+ int boatid = punit->transported_by;
+ struct unit *ferryboat = NULL;
+
+ UNIT_LOG(LOGLEVEL_GOTHERE, punit, "will have to go to (%d,%d) by boat",
+ dest_x, dest_y);
+
+ if (boatid <= 0) {
+ int bx, by;
+ boatid = find_boat(pplayer, &bx, &by, 2);
+ }
+ ferryboat = find_unit_by_id(boatid);
+
+ if (!ferryboat) {
+ UNIT_LOG(LOGLEVEL_GOTHERE, punit, "No boat found.");
+ if (is_at_coast(punit->x, punit->y)) {
+ punit->ai.ferryboat = FERRY_WANTED;
+ }
+ return FALSE;
+ } else {
+ UNIT_LOG(LOGLEVEL_GOTHERE, punit, "Found boat at (%d,%d)",
+ ferryboat->x, ferryboat->y);
+ }
+
punit->ai.ferryboat = boatid;
- UNIT_LOG(LOG_DEBUG, punit, "Looking for boat[%d].", boatid);
- if (boatid > 0 && !same_pos(x, y, bx, by)) {
- /* Go to the boat */
+ if (!same_pos(punit->x, punit->y, ferryboat->x, ferryboat->y)
+ && (!is_at_coast(punit->x, punit->y)
+ || is_tiles_adjacent(punit->x, punit->y,
+ ferryboat->x, ferryboat->y))) {
+ /* Go to the boat only if it cannot reach us or it's parked
+ * next to us. Otherwise just wait (boats are normally faster) */
+ /* FIXME: agree on a rendez-vous point */
/* FIXME: this can lose bodyguard */
- if (!ai_unit_goto(punit, bx, by)) {
+ UNIT_LOG(LOGLEVEL_GOTHERE, punit, "going to boat[%d](%d,%d).", boatid,
+ ferryboat->x, ferryboat->y);
+ if (!ai_unit_goto(punit, ferryboat->x, ferryboat->y)) {
/* Died. */
return FALSE;
}
+ }
+
+ if (!same_pos(punit->x, punit->y, ferryboat->x, ferryboat->y)) {
+ /* Didn't get to the boat */
+ if (is_at_coast(punit->x, punit->y)) {
+ /* At least got to the coast, wave to the boats! */
+ UNIT_LOG(LOGLEVEL_GOTHERE, punit, "asking a boat to come nearer");
+ punit->ai.ferryboat = FERRY_WANTED;
+ }
+ return FALSE;
}
- ptile = map_get_tile(punit->x, punit->y);
- ferryboat = unit_list_find(&ptile->units, punit->ai.ferryboat);
- if (ferryboat && (ferryboat->ai.passenger == 0
- || ferryboat->ai.passenger == punit->id)) {
- int boat_x, boat_y;
+ /* Check if we are the passenger-in-charge */
+ if (ferryboat->ai.passenger == 0
+ || ferryboat->ai.passenger == punit->id) {
+ struct tile *ptile;
+ int beach_x, beach_y; /* Destination for the boat */
+ struct tile *dest_tile = map_get_tile(dest_x, dest_y);
+ struct unit *def;
- UNIT_LOG(LOG_DEBUG, punit, "Found boat[%d], going (%d,%d)",
+ UNIT_LOG(LOGLEVEL_GOTHERE, punit, "got boat[%d], going (%d,%d)",
ferryboat->id, dest_x, dest_y);
handle_unit_activity_request(punit, ACTIVITY_SENTRY);
ferryboat->ai.passenger = punit->id;
- /* Last ingredient: a beachhead. */
- if (find_beachhead(punit, dest_x, dest_y, &boat_x, &boat_y)) {
- UNIT_LOG(LOG_DEBUG, punit, "Found beachhead (%d,%d), all aboard",
- boat_x, boat_y);
- set_goto_dest(ferryboat, boat_x, boat_y);
- set_goto_dest(punit, dest_x, dest_y);
- unit_list_iterate(ptile->units, mypass) {
- if (mypass->ai.ferryboat == ferryboat->id
- && punit->owner == mypass->owner) {
- handle_unit_activity_request(mypass, ACTIVITY_SENTRY);
- def = unit_list_find(&ptile->units, mypass->ai.bodyguard);
- if (def) {
- handle_unit_activity_request(def, ACTIVITY_SENTRY);
- }
- }
- } unit_list_iterate_end; /* passengers are safely stowed away */
- if (!ai_unit_goto(ferryboat, dest_x, dest_y)) {
- return FALSE; /* died */
+ /* If the location is not accessible directly from sea
+ * or is defended and we are not marines, we will need a
+ * landing beach */
+ if (!is_at_coast(dest_x, dest_y)
+ ||((is_non_allied_city_tile(dest_tile, pplayer)
+ || is_non_allied_unit_tile(dest_tile, pplayer))
+ && !unit_flag(punit, F_MARINES))) {
+ if (!find_beachhead(punit, dest_x, dest_y, &beach_x, &beach_y)) {
+ /* Nowhere to go */
+ return FALSE;
}
+ UNIT_LOG(LOGLEVEL_GOTHERE, punit,
+ "Found beachhead (%d,%d)", beach_x, beach_y);
+ } else {
+ beach_x = dest_x;
+ beach_y = dest_y;
}
- }
- }
- if (ferryboat && is_goto_dest_set(ferryboat)) {
- /* we are on a ferry! did we arrive? */
- boat_arrived = same_pos(ferryboat->x, ferryboat->y,
- goto_dest_x(ferryboat), goto_dest_y(ferryboat))
- || is_tiles_adjacent(ferryboat->x, ferryboat->y,
- goto_dest_x(ferryboat), goto_dest_y(ferryboat));
- } else {
- boat_arrived = FALSE;
- }
+ UNIT_LOG(LOGLEVEL_GOTHERE, punit, "All aboard!");
+ set_goto_dest(ferryboat, beach_x, beach_y);
+ set_goto_dest(punit, dest_x, dest_y);
+ /* Sentry the passengers */
+ ptile = map_get_tile(punit->x, punit->y);
+ unit_list_iterate(ptile->units, mypass) {
+ if (mypass->ai.ferryboat == ferryboat->id
+ && punit->owner == mypass->owner) {
+ handle_unit_activity_request(mypass, ACTIVITY_SENTRY);
+ def = unit_list_find(&ptile->units, mypass->ai.bodyguard);
+ if (def) {
+ handle_unit_activity_request(def, ACTIVITY_SENTRY);
+ }
+ }
+ } unit_list_iterate_end;
- if (boat_arrived) {
+ if (!ai_unit_goto(ferryboat, beach_x, beach_y)) {
+ /* died */
+ return FALSE;
+ }
+ if (!is_tiles_adjacent(ferryboat->x, ferryboat->y, beach_x, beach_y)
+ && !same_pos(ferryboat->x, ferryboat->y, beach_x, beach_y)) {
+ /* We are in still transit */
+ return FALSE;
+ }
+ } else {
+ /* Waiting for the boss to load and move us */
+ UNIT_LOG(LOGLEVEL_GOTHERE, punit, "Cannot command boat [%d]",
+ ferryboat->id);
+ return FALSE;
+ }
+
+ UNIT_LOG(LOGLEVEL_GOTHERE, punit, "Our boat has arrived");
handle_unit_activity_request(punit, ACTIVITY_IDLE);
- UNIT_LOG(LOG_DEBUG, punit, "Our boat has arrived");
}
/* Go where we should be going if we can, and are at our destination
* if we are on a ferry */
- if (goto_is_sane(punit, dest_x, dest_y, TRUE) && punit->moves_left > 0
- && (!ferryboat || boat_arrived)) {
+ if (goto_is_sane(punit, dest_x, dest_y, TRUE) && punit->moves_left > 0) {
set_goto_dest(punit, dest_x, dest_y);
- UNIT_LOG(LOG_DEBUG, punit, "Attempt to walk to (%d,%d)", dest_x, dest_y);
+ UNIT_LOG(LOGLEVEL_GOTHERE, punit, "Walking to (%d,%d)", dest_x, dest_y);
if (!ai_unit_goto(punit, dest_x, dest_y)) {
/* died */
return FALSE;
}
/* liable to bump into someone that will kill us. Should avoid? */
} else {
- UNIT_LOG(LOG_DEBUG, punit, "Not moving");
+ UNIT_LOG(LOGLEVEL_GOTHERE, punit, "Not moving");
+ return FALSE;
}
/* Dead unit shouldn't reach this point */
CHECK_UNIT(punit);
- return (!same_pos(punit->x, punit->y, x, y));
+ return (same_pos(punit->x, punit->y, dest_x, dest_y)
+ || is_tiles_adjacent(punit->x, punit->y, dest_x, dest_y));
}
/*************************************************************************
@@ -2249,32 +2300,28 @@
/* Then find enemies the hard way */
find_something_to_kill(pplayer, punit, &dest_x, &dest_y);
if (!same_pos(punit->x, punit->y, dest_x, dest_y)) {
- int repeat;
-
- for(repeat = 0; repeat < 2; repeat++) {
if (!is_tiles_adjacent(punit->x, punit->y, dest_x, dest_y)
- || !can_unit_attack_tile(punit, dest_x, dest_y)
- || (could_unit_move_to_tile(punit, dest_x, dest_y) == 0)) {
- /* Can't attack or move usually means we are adjacent but
- * on a ferry. This fixes the problem (usually). */
+ || !can_unit_attack_tile(punit, dest_x, dest_y)) {
+ /* Adjacent and can't attack usually means we are not marines
+ * and on a ferry. This fixes the problem (usually). */
UNIT_LOG(LOG_DEBUG, punit, "mil att gothere -> (%d,%d)",
dest_x, dest_y);
if (!ai_military_gothere(pplayer, punit, dest_x, dest_y)) {
/* Died or got stuck */
return;
}
- } else {
- /* Close combat. fstk sometimes want us to attack an adjacent
- * enemy that rampage wouldn't */
- UNIT_LOG(LOG_DEBUG, punit, "mil att bash -> %d, %d", dest_x, dest_y);
- if (!ai_unit_attack(punit, dest_x, dest_y)) {
- /* Died */
+ /* Must be adjacent now. */
+ }
+
+ /* Close combat. fstk sometimes want us to attack an adjacent
+ * enemy that rampage wouldn't */
+ UNIT_LOG(LOG_DEBUG, punit, "mil att bash -> %d, %d", dest_x, dest_y);
+ if (!ai_unit_attack(punit, dest_x, dest_y)) {
+ /* Died */
return;
- }
}
- } /* for-loop */
} else {
/* FIXME: This happens a bit too often! */
UNIT_LOG(LOG_DEBUG, punit, "fstk didn't find us a worthy target!");
@@ -2406,164 +2453,168 @@
}
}
-/**************************************************************************
-This seems to manage the ferryboat. When it carries units on their way
-to invade something, it goes there. If it carries other units, it returns home.
-When empty, it tries to find some units to carry or goes home or explores.
-Military units handled by ai_manage_military()
-**************************************************************************/
+#define LOGLEVEL_FERRY LOG_NORMAL
+/****************************************************************************
+ It's about 12 feet square and has a capacity of almost 1000 pounds.
+ It is well constructed of teak, and looks seaworthy.
+
+ Manage ferryboat. If there is a passenger-in-charge, we let it drive the
+ boat. If there isn't, appoint one from those we have on board.
+
+ If there is no one aboard, look for potential cargo. If none found,
+ explore and then go to the nearest port.
+****************************************************************************/
static void ai_manage_ferryboat(struct player *pplayer, struct unit *punit)
-{ /* It's about 12 feet square and has a capacity of almost 1000 pounds.
- It is well constructed of teak, and looks seaworthy. */
+{
struct city *pcity;
- struct city *port = NULL;
- struct unit *bodyguard = NULL;
- struct unit_type *punittype = get_unit_type(punit->type);
- int best = 4 * punittype->move_rate, x = punit->x, y = punit->y;
- int n = 0, p = 0;
+ struct tile *ptile = map_get_tile(punit->x, punit->y);
CHECK_UNIT(punit);
-
- if (!unit_list_find(&map_get_tile(punit->x, punit->y)->units,
punit->ai.passenger)) {
- punit->ai.passenger = 0;
- }
-
- unit_list_iterate(map_get_tile(punit->x, punit->y)->units, aunit)
- if (punit->owner != aunit->owner) {
- continue;
- }
- if (aunit->ai.ferryboat == punit->id) {
- if (punit->ai.passenger == 0) {
- punit->ai.passenger = aunit->id; /* oops */
- }
- if (is_military_unit(aunit) && punit->ai.bodyguard == BODYGUARD_NONE) {
- /* Acquire some protection as we deliver an invasion army */
- UNIT_LOG(LOG_DEBUG, punit, "shout out for a bodyguard");
- punit->ai.bodyguard = BODYGUARD_WANTED;
- }
- p++;
- bodyguard = unit_list_find(&map_get_tile(punit->x, punit->y)->units,
aunit->ai.bodyguard);
- if (is_goto_dest_set(aunit)) { /* HACK */
- pcity = map_get_city(goto_dest_x(aunit), goto_dest_y(aunit));
- } else {
- pcity = NULL;
- }
- if (aunit->ai.bodyguard == BODYGUARD_NONE || bodyguard ||
- (pcity && pcity->ai.invasion >= 2)) {
- if (pcity) {
- UNIT_LOG(LOG_DEBUG, punit, "Ferrying to %s to %s, invasion = %d, body
= %d",
- unit_name(aunit->type), pcity->name,
- pcity->ai.invasion, aunit->ai.bodyguard);
- }
- n++;
- handle_unit_activity_request(aunit, ACTIVITY_SENTRY);
- if (bodyguard) {
- handle_unit_activity_request(bodyguard, ACTIVITY_SENTRY);
- }
- }
- }
- unit_list_iterate_end;
- /* we try to recover hitpoints if we are in a city, before we leave */
- if (punit->hp < punittype->hp
+ /* Try to recover hitpoints if we are in a city, before we do anything */
+ if (punit->hp < unit_type(punit)->hp
&& (pcity = map_get_city(punit->x, punit->y))) {
- /* Don't do anything, just wait in the city */
- UNIT_LOG(LOG_DEBUG, punit, "waiting in %s to recover hitpoints "
- "before ferrying", pcity->name);
+ UNIT_LOG(LOGLEVEL_FERRY, punit, "waiting in %s to recover hitpoints",
+ pcity->name);
return;
}
- if (p != 0) {
- UNIT_LOG(LOG_DEBUG, punit, "in manage_ferryboat p=%d, n=%d", p, n);
- if (is_goto_dest_set(punit) && punit->moves_left > 0 && n != 0) {
- (void) ai_unit_gothere(punit);
- } else if (n == 0 && !map_get_city(punit->x, punit->y)) { /* rest in a
city, for unhap */
- port = find_nearest_safe_city(punit);
- if (port && !ai_unit_goto(punit, port->x, port->y)) {
- return; /* oops! */
- }
- send_unit_info(pplayer, punit); /* to get the crosshairs right -- Syela
*/
- } else {
- UNIT_LOG(LOG_DEBUG, punit, "Ferryboat %d@(%d,%d) stalling.",
- punit->id, punit->x, punit->y);
- if(is_barbarian(pplayer)) /* just in case */
- (void) ai_manage_explorer(punit);
- }
+ /* Check if we are an empty barbarian boat and so not needed */
+ if (is_barbarian(pplayer)
+ && unit_list_size(&ptile->units) < 2 ) {
+ wipe_unit(punit);
return;
}
- /* check if barbarian boat is empty and so not needed - the crew has landed
*/
- if( is_barbarian(pplayer) && unit_list_size(&map_get_tile(punit->x,
punit->y)->units)<2 ) {
- wipe_unit(punit);
- return;
+ /* Do we have the passenger-in-charge on board? */
+ if (punit->ai.passenger != 0
+ && !unit_list_find(&ptile->units, punit->ai.passenger)) {
+ UNIT_LOG(LOGLEVEL_FERRY, punit, "lost psngr-in-charge [%d], resetting",
+ punit->ai.passenger);
+ punit->ai.passenger = 0;
}
- /* ok, not carrying anyone, even the ferryman */
- punit->ai.passenger = 0;
- UNIT_LOG(LOG_DEBUG, punit, "Ferryboat is lonely.");
- handle_unit_activity_request(punit, ACTIVITY_IDLE);
-
- /* Release bodyguard and let it roam */
- ai_unit_new_role(punit, AIUNIT_NONE, -1, -1);
- if (bodyguard) {
- ai_military_attack(pplayer, bodyguard);
+ if (punit->ai.passenger == 0) {
+ struct unit *bodyguard = NULL;
+
+ /* Try to select passanger-in-charge from among their passengers */
+ unit_list_iterate(ptile->units, aunit) {
+ if (aunit->ai.ferryboat != punit->id) {
+ continue;
+ }
+
+ if (aunit->ai.ai_role != AIUNIT_ESCORT) {
+ /* Bodyguards shouldn't be in charge of boats... */
+ UNIT_LOG(LOGLEVEL_FERRY, punit,
+ "appointed %s[%d] our psngr-in-charge",
+ unit_type(aunit)->name, aunit->id);
+ punit->ai.passenger = aunit->id;
+ break;
+ } else {
+ bodyguard = aunit;
+ }
+ } unit_list_iterate_end;
+
+ if (punit->ai.passenger == 0 && bodyguard) {
+ UNIT_LOG(LOGLEVEL_FERRY, punit,
+ "has to take %s[%d] as our psngr-in-charge",
+ unit_type(bodyguard)->name, bodyguard->id);
+ punit->ai.passenger = bodyguard->id;
+ }
}
- if (IS_ATTACKER(punit)) {
- if (punit->moves_left > 0) ai_manage_military(pplayer, punit);
- return;
- } /* AI used to build frigates to attack and then use them as ferries --
Syela */
+ if (punit->ai.passenger != 0) {
+ int bossid = punit->ai.passenger; /* For reference */
+ struct unit *boss = find_unit_by_id(bossid);
+ int id = punit->id; /* To check if survived */
+ int moves_left = punit->moves_left; /* Loop prevention */
+
+ assert(boss);
- /*** Find work ***/
- CHECK_UNIT(punit);
+ if (unit_flag(boss, F_SETTLERS) || unit_flag(boss, F_CITIES)) {
+ /* Temporary hack: settlers all go in the end, forcing them
+ * earlier might mean uninitialised cache, so just wait for them */
+ return;
+ }
- generate_warmap(map_get_city(punit->x, punit->y), punit);
- p = 0; /* yes, I know it's already zero. -- Syela */
- best = 9999;
- x = -1; y = -1;
- unit_list_iterate(pplayer->units, aunit) {
- if (aunit->ai.ferryboat != 0
- && WARMAP_SEACOST(aunit->x, aunit->y) < best
- && ground_unit_transporter_capacity(aunit->x, aunit->y, pplayer) <= 0
- && is_at_coast(aunit->x, aunit->y)) {
- UNIT_LOG(LOG_DEBUG, punit, "Found a potential pickup %d@(%d, %d)",
- aunit->id, aunit->x, aunit->y);
- x = aunit->x;
- y = aunit->y;
- best = WARMAP_SEACOST(x, y);
- }
- if (is_sailing_unit(aunit)
- && is_ocean(map_get_terrain(aunit->x, aunit->y))) {
- p++;
+ UNIT_LOG(LOGLEVEL_FERRY, punit, "passing control to %s[%d]",
+ unit_type(boss)->name, bossid);
+ ai_manage_unit(pplayer, boss);
+
+ if (!find_unit_by_id(id) || punit->moves_left < moves_left) {
+ return;
}
- } unit_list_iterate_end;
- if (best < 4 * unit_type(punit)->move_rate) {
- /* Pickup is within 4 turns to grab, so move it! */
- set_goto_dest(punit, x, y);
- UNIT_LOG(LOG_DEBUG, punit, "Found a friend and going to him @(%d, %d)",
- x, y);
- (void) ai_unit_gothere(punit);
- return;
- }
+ /* We are alive and didn't spend any moves. We are stuck!
+ * NB: it can be that punit->ai.passenger has changed by now,
+ * for example if the boss has landed */
+ UNIT_LOG(LOGLEVEL_FERRY, punit, "taking control back from [%d]",
+ bossid);
- /* do cool stuff here */
- CHECK_UNIT(punit);
+ } else {
+ /* Not carrying anyone, even the ferryman */
- if (punit->moves_left == 0) return;
- pcity = find_city_by_id(punit->homecity);
- if (pcity) {
- if (!ai_handicap(pplayer, H_TARGETS) ||
- unit_move_turns(punit, pcity->x, pcity->y) < p) {
- set_goto_dest(punit, pcity->x, pcity->y);
- UNIT_LOG(LOG_DEBUG, punit, "No friends. Going home.");
- (void) ai_unit_gothere(punit);
+ /* Path-finding stuff */
+ struct pf_map *map;
+ struct pf_parameter parameter;
+
+ if (IS_ATTACKER(punit) && punit->moves_left > 0) {
+ /* AI used to build frigates to attack and then use them as ferries
+ * -- Syela */
+ ai_manage_military(pplayer, punit);
return;
}
+
+ UNIT_LOG(LOGLEVEL_FERRY, punit, "Ferryboat is looking for cargo.");
+ handle_unit_activity_request(punit, ACTIVITY_IDLE);
+ CHECK_UNIT(punit);
+
+ pft_fill_default_parameter(¶meter);
+ pft_fill_unit_overlap_param(¶meter, punit);
+ /* We are looking for our units, no need to look into the unknown */
+ parameter.get_TB = no_fights_or_unknown;
+ parameter.omniscience = FALSE;
+
+ map = pf_create_map(¶meter);
+ while (pf_next(map)) {
+ struct pf_position pos;
+
+ pf_next_get_position(map, &pos);
+
+ unit_list_iterate(map_get_tile(pos.x, pos.y)->units, aunit) {
+ if (aunit->ai.ferryboat == FERRY_WANTED) {
+ UNIT_LOG(LOGLEVEL_FERRY, punit,
+ "Found a potential cargo %s[%d](%d,%d), going there",
+ unit_type(aunit)->name, aunit->id, aunit->x, aunit->y);
+ set_goto_dest(punit, aunit->x, aunit->y);
+ aunit->ai.ferryboat = punit->id;
+ pf_destroy_map(map);
+ /* FIXME: lift the path off the map */
+ (void) ai_unit_gothere(punit);
+ return;
+ }
+ } unit_list_iterate_end;
+ }
+
+ pf_destroy_map(map);
}
- if (is_ocean(map_get_terrain(punit->x, punit->y))) {
- /* thanks, Tony */
- (void) ai_manage_explorer(punit);
+
+ CHECK_UNIT(punit);
+
+ if (punit->moves_left == 0
+ || !is_ocean(map_get_terrain(punit->x, punit->y))) {
+ return;
}
+
+ (void) ai_manage_explorer(punit);
+ if (punit->moves_left > 0) {
+ struct city *pcity = find_nearest_safe_city(punit);
+ if (pcity) {
+ set_goto_dest(punit, pcity->x, pcity->y);
+ UNIT_LOG(LOGLEVEL_FERRY, punit, "No work, going home");
+ (void) ai_unit_gothere(punit);
+ }
+ }
+
return;
}
Index: ai/aiunit.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.h,v
retrieving revision 1.49
diff -u -r1.49 aiunit.h
--- ai/aiunit.h 2003/09/27 11:22:40 1.49
+++ ai/aiunit.h 2003/09/28 11:41:24
@@ -46,6 +46,8 @@
extern Unit_Type_id simple_ai_types[U_LAST];
+bool ai_military_gothere(struct player *pplayer, struct unit *punit,
+ int dest_x, int dest_y);
void ai_manage_units(struct player *pplayer);
int could_unit_move_to_tile(struct unit *punit, int dest_x, int dest_y);
int look_for_charge(struct player *pplayer, struct unit *punit,
Index: server/settlers.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/settlers.c,v
retrieving revision 1.173
diff -u -r1.173 settlers.c
--- server/settlers.c 2003/09/23 15:59:05 1.173
+++ server/settlers.c 2003/09/28 11:41:25
@@ -54,6 +54,8 @@
BV_DEFINE(enemy_mask, MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS);
static enemy_mask enemies[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS];
+static void auto_settler_findwork(struct player *pplayer,
+ struct unit *punit);
static void auto_settlers_player(struct player *pplayer);
static bool is_already_assigned(struct unit *myunit, struct player *pplayer,
int x, int y);
@@ -1187,6 +1189,7 @@
return best_newv;
}
+#if 0
/**************************************************************************
Handles GOTO for settlers. Only ever used in auto_settler_findwork
below.
@@ -1255,6 +1258,7 @@
return TRUE;
}
+#endif /* ifdef 0 */
/**************************************************************************
find some work for the settler
@@ -1311,8 +1315,8 @@
}
/* We've now worked out what to do; go to it! */
- if (!ai_gothere(punit, gx, gy, ferryboat)) {
- /* died */
+ if (!ai_military_gothere(pplayer, punit, gx, gy)) {
+ /* Died or got stuck */
return;
}
@@ -1384,7 +1388,7 @@
freelog(LOG_DEBUG, "Warmth = %d, game.globalwarming=%d",
pplayer->ai.warmth, game.globalwarming);
unit_list_iterate(pplayer->units, punit) {
- if (punit->ai.control
+ if ((punit->ai.control || pplayer->ai.control)
&& (unit_flag(punit, F_SETTLERS)
|| unit_flag(punit, F_CITIES))) {
freelog(LOG_DEBUG, "%s's settler at (%d, %d) is ai controlled.",
- [freeciv-ai] Re: (PR#6308) Cleanup of ferry handling,
Gregory Berkolaiko <=
|
|