[Freeciv-Dev] (PR#9959) Re: [freeciv-ai] Re: Inprovements in settler.c
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: |
undisclosed-recipients: ; |
Subject: |
[Freeciv-Dev] (PR#9959) Re: [freeciv-ai] Re: Inprovements in settler.c |
From: |
"Per I. Mathisen" <per@xxxxxxxxxxx> |
Date: |
Sun, 5 Sep 2004 13:31:28 -0700 |
Reply-to: |
rt@xxxxxxxxxxx |
<URL: http://rt.freeciv.org/Ticket/Display.html?id=9959 >
On Wed, 1 Sep 2004, Jordi Negrevernis i Font wrote:
> Updated to current CVS. I did not test fuly because the cvs-Aug-29
> crashed a lot - cma specialy.
Here is another updated patch. I changed the if-logic a little to waste
fewer CPU-cycles and made it return when failing to build cities.
TODO:
- the borders check should also check if we are using borders in the
server (iirc game.borders)
- we should use the movemap code instead of enemies_at(), because
enemies_at() is really insufficient here
So I wish to delay this patch until we have the movemap in cvs, and
movemap is currently waiting for Greg's new pf patch.
- Per
Index: ai/aitools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitools.c,v
retrieving revision 1.122
diff -u -r1.122 aitools.c
--- ai/aitools.c 2 Sep 2004 14:58:23 -0000 1.122
+++ ai/aitools.c 5 Sep 2004 20:25:20 -0000
@@ -425,7 +425,7 @@
bodyguard has not. This is an ai_unit_* auxiliary function, do not use
elsewhere.
**************************************************************************/
-static void ai_unit_bodyguard_move(int unitid, int x, int y)
+void ai_unit_bodyguard_move(int unitid, int x, int y)
{
struct unit *bodyguard = find_unit_by_id(unitid);
struct unit *punit;
@@ -459,7 +459,7 @@
Repair incompletely referenced bodyguards. When the rest of the bodyguard
mess is cleaned up, this repairing should be replaced with an assert.
**************************************************************************/
-static bool has_bodyguard(struct unit *punit)
+bool has_bodyguard(struct unit *punit)
{
struct unit *guard;
if (punit->ai.bodyguard > BODYGUARD_NONE) {
Index: ai/aitools.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitools.h,v
retrieving revision 1.46
diff -u -r1.46 aitools.h
--- ai/aitools.h 3 Sep 2004 04:22:36 -0000 1.46
+++ ai/aitools.h 5 Sep 2004 20:25:20 -0000
@@ -51,6 +51,7 @@
bool ai_unit_make_homecity(struct unit *punit, struct city *pcity);
bool ai_unit_attack(struct unit *punit, int x, int y);
bool ai_unit_move(struct unit *punit, int x, int y);
+void ai_unit_bodyguard_move(int unitid, int x, int y);
struct city *dist_nearest_city(struct player *pplayer, int x, int y,
bool everywhere, bool enemy);
@@ -69,4 +70,7 @@
bool is_player_dangerous(struct player *pplayer, struct player *aplayer);
+bool has_bodyguard(struct unit *punit);
+
+
#endif /* FC__AITOOLS_H */
Index: ai/aiunit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
retrieving revision 1.334
diff -u -r1.334 aiunit.c
--- ai/aiunit.c 1 Sep 2004 11:47:25 -0000 1.334
+++ ai/aiunit.c 5 Sep 2004 20:25:20 -0000
@@ -903,6 +903,34 @@
}
/*************************************************************************
+ Tries to find a land tile adjacent to a unit to defend from an attack
+ (dest_x, dest_y). Prefers tiles which are more defensible.
+**************************************************************************/
+bool find_defending_spot(struct unit *punit, int *x, int *y)
+{
+ int ok, best = 0;
+ enum tile_terrain_type t;
+
+ CHECK_UNIT(punit);
+
+ adjc_iterate(punit->x, punit->y, x1, y1) {
+ ok = 0;
+ t = map_get_terrain(x1, y1);
+ if (!is_ocean(t) && is_my_zoc(unit_owner(punit), x1, y1)) {
+ /* accessible tile nearby */
+ ok = get_tile_type(t)->defense_bonus;
+ if (ok > best) {
+ best = ok;
+ *x = x1;
+ *y = y1;
+ }
+ }
+ } adjc_iterate_end;
+
+ return (best > 0);
+}
+
+/*************************************************************************
Does the unit with the id given have the flag L_DEFEND_GOOD?
**************************************************************************/
static bool unit_role_defender(Unit_Type_id type)
Index: ai/aiunit.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.h,v
retrieving revision 1.54
diff -u -r1.54 aiunit.h
--- ai/aiunit.h 3 Sep 2004 04:22:36 -0000 1.54
+++ ai/aiunit.h 5 Sep 2004 20:25:21 -0000
@@ -64,6 +64,7 @@
int *x, int *y);
bool find_beachhead(struct unit *punit, int dest_x, int dest_y,
int *x, int *y);
+bool find_defending_spot(struct unit *punit, int *x, int *y);
int build_cost_balanced(Unit_Type_id type);
int unittype_att_rating(Unit_Type_id type, int veteran,
Index: server/settlers.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/settlers.c,v
retrieving revision 1.199
diff -u -r1.199 settlers.c
--- server/settlers.c 31 Aug 2004 04:40:51 -0000 1.199
+++ server/settlers.c 5 Sep 2004 20:25:22 -0000
@@ -63,6 +63,8 @@
{
int x = punit->x, y = punit->y;
struct city *pcity;
+ int bodyguard = punit->ai.bodyguard;
+ struct unit *pbody = find_unit_by_id(bodyguard);
assert(pplayer == unit_owner(punit));
handle_unit_activity_request(punit, ACTIVITY_IDLE);
@@ -79,6 +81,14 @@
return FALSE;
}
+ /* If we carried a bodyguard just use it!.
+ * Its the new defender of the city */
+ if (pbody) {
+ if (ai_unit_make_homecity(pbody, pcity)) {
+ ai_unit_new_role(pbody, AIUNIT_ESCORT, -1, -1);
+ }
+ }
+
/* We have to rebuild at least the cache for this city. This event is
* rare enough we might as well build the whole thing. Who knows what
* else might be cached in the future? */
@@ -145,11 +155,34 @@
**************************************************************************/
void ai_manage_settler(struct player *pplayer, struct unit *punit)
{
+ bool pos_dangerous = 0;
+
punit->ai.control = TRUE;
/* if BUILD_CITY must remain BUILD_CITY, otherwise turn into autosettler */
if (punit->ai.ai_role == AIUNIT_NONE) {
ai_unit_new_role(punit, AIUNIT_AUTO_SETTLER, -1, -1);
}
+
+ /* If goto is set and we do not have a bodyguard, check if we are in or
+ * are headed for a dangerous position. */
+ if (!has_bodyguard(punit)) {
+ if (is_goto_dest_set(punit)) {
+ pos_dangerous = enemies_at(punit, goto_dest_x(punit), goto_dest_y(punit))
+ || map_get_owner(goto_dest_x(punit), goto_dest_y(punit))
+ != pplayer;
+ } else {
+ /* otherwise we check for the current location */
+ pos_dangerous = enemies_at(punit, punit->x, punit->y);
+ }
+
+ if (pos_dangerous > 0) {
+ punit->ai.bodyguard = BODYGUARD_WANTED;
+ }
+ } else {
+ UNIT_LOG(LOG_DEBUG, punit, "with a bodyguard!");
+ ai_unit_bodyguard_move(punit->ai.bodyguard, punit->x, punit->y);
+ }
+
return;
}
@@ -1096,23 +1129,39 @@
ai_unit_new_role(punit, AIUNIT_NONE, -1, -1);
return; /* avoid recursion at all cost */
} else {
- /* Go there */
- if ((!ai_gothere(pplayer, punit, x, y) && !find_unit_by_id(sanity))
- || punit->moves_left <= 0) {
+ if (enemies_at(punit, punit->x, punit->y) && !has_bodyguard(punit)) {
+ /* there are enemies at current location! so scatter and hide */
+ UNIT_LOG(LOG_SETTLER, punit, "enemies side by side settler!");
+ if (find_defending_spot(punit, &gx, &gy)) {
+ ai_unit_goto(punit, gx, gy);
+ }
return;
- }
- if (same_pos(punit->x, punit->y, x, y)) {
- if (!ai_do_build_city(pplayer, punit)) {
- UNIT_LOG(LOG_ERROR, punit, "could not make city on %s",
- map_get_tile_info_text(punit->x, punit->y));
- ai_unit_new_role(punit, AIUNIT_NONE, -1, -1);
- } else {
- return; /* We came, we saw, we built... */
- }
} else {
- UNIT_LOG(LOG_SETTLER, punit, "could not go to target");
- /* ai_unit_new_role(punit, AIUNIT_NONE, -1, -1); */
- return;
+ if (enemies_at(punit, x, y) && !has_bodyguard(punit)) {
+ /* there are enemies at destination! */
+ UNIT_LOG(LOG_SETTLER, punit, "enemies at city founding location!");
+ return;
+ } else {
+ /* Go there */
+ if ((!ai_gothere(pplayer, punit, x, y) && !find_unit_by_id(sanity))
+ || punit->moves_left <= 0) {
+ return;
+ }
+ if (same_pos(punit->x, punit->y, x, y)) {
+ if (!ai_do_build_city(pplayer, punit)) {
+ UNIT_LOG(LOG_ERROR, punit, "could not make city on %s",
+ map_get_tile_info_text(punit->x, punit->y));
+ ai_unit_new_role(punit, AIUNIT_NONE, -1, -1);
+ return;
+ } else {
+ return; /* We came, we saw, we built... */
+ }
+ } else {
+ UNIT_LOG(LOG_SETTLER, punit, "we are en route");
+ /* ai_unit_new_role(punit, AIUNIT_NONE, -1, -1); */
+ return;
+ }
+ }
}
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Freeciv-Dev] (PR#9959) Re: [freeciv-ai] Re: Inprovements in settler.c,
Per I. Mathisen <=
|
|