[Freeciv-Dev] Re: (PR#3776) Goto sees ZOC but ignores it
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
On Wed, 16 Jul 2003, Jason Short wrote:
> OK, I see. Now I understand what the problem was originally...
>
> However, this solution is incomplete. Now for the client goto map we
> check ZOC. But any other PF in the client (that uses
> simple_path_unit_iterator) will still use the server's version by default.
>
> In other words, the server implementation should be in the server not in
> the common code. One alternative might be to have the common-code
> implementation work for both server and client. This would be ugly
> (checking is_server) but at least it would be localized.
Attached is a version that still uses callbacks (maybe useful later), but
so far there is only one such callback: is_my_zoc in
common/unit.c,suitably peppered with is_server checks.
G.
Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.176
diff -u -r1.176 unit.c
--- common/unit.c 2003/07/02 16:48:55 1.176
+++ common/unit.c 2003/07/16 22:54:54
@@ -1145,20 +1145,41 @@
}
/**************************************************************************
- Is this square controlled by the unit's owner?
+ Is this square controlled by the pplayer?
- Here "is_my_zoc" means essentially a square which is
- *not* adjacent to an enemy unit on a land tile.
- (Or, currently, an enemy city even if empty.)
+ Here "is_my_zoc" means essentially a square which is *not* adjacent to an
+ enemy unit on a land tile.
Note this function only makes sense for ground units.
+
+ Since this function is also used in the client, it has to deal with some
+ client-specific features, like FoW and the fact that the client cannot
+ see units inside enemy cities.
**************************************************************************/
-bool is_my_zoc(struct player *unit_owner, int x0, int y0)
+bool is_my_zoc(struct player *pplayer, int x0, int y0)
{
square_iterate(x0, y0, 1, x1, y1) {
- if (!is_ocean(map_get_terrain(x1, y1))
- && is_non_allied_unit_tile(map_get_tile(x1, y1), unit_owner))
+ struct tile *ptile = map_get_tile(x1, y1);
+
+ if (is_ocean(ptile->terrain)) {
+ continue;
+ }
+ if (is_non_allied_unit_tile(ptile, pplayer)) {
+ /* Note: in the client, the above function will return NULL
+ * if there is a city there, even if the city is occupied */
return FALSE;
+ }
+
+ if (!is_server) {
+ struct city *pcity = is_non_allied_city_tile(ptile, pplayer);
+
+ if (pcity
+ && (pcity->occupied
+ || map_get_known2(x1, y1, pplayer) == TILE_KNOWN_FOGGED)) {
+ /* If the city is fogged, we assume it's occupied */
+ return FALSE;
+ }
+ }
} square_iterate_end;
return TRUE;
Index: common/aicore/path_finding.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/path_finding.c,v
retrieving revision 1.9
diff -u -r1.9 path_finding.c
--- common/aicore/path_finding.c 2003/05/03 13:28:48 1.9
+++ common/aicore/path_finding.c 2003/07/16 22:54:55
@@ -205,17 +205,18 @@
node->behavior = TB_NORMAL;
}
- if (params->zoc_used) {
+ if (params->get_zoc) {
struct tile *tile = map_get_tile(x, y);
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 */
- /* 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));
+ || params->get_zoc(params->owner, x, y));
+ /* ZoC rules cannot prevent us from moving into/attacking an occupied
+ * tile. Other rules can, but we don't care about them here. */
+ bool occupied = (unit_list_size(&(map_get_tile(x, y)->units)) > 0
+ || map_get_city(x, y));
+
+ /* 2 means can move unrestricted from/into it,
+ * 1 means can move unrestricted into it, but not necessarily from it */
+ node->zoc_number = (my_zoc ? 2 : (occupied ? 1 : 0));
}
/* Evaluate the extra cost of the destination */
@@ -279,7 +280,7 @@
}
/* Is the move ZOC-ok? */
- if (pf_map->params->zoc_used
+ if (pf_map->params->get_zoc
&& !(node->zoc_number > 1 || node1->zoc_number > 0)) {
continue;
}
@@ -834,7 +835,7 @@
}
/* Is the move ZOC-ok? */
- if (pf_map->params->zoc_used
+ if (pf_map->params->get_zoc
&& !(node->zoc_number > 1 || node1->zoc_number > 2)) {
continue;
}
Index: common/aicore/path_finding.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/path_finding.h,v
retrieving revision 1.2
diff -u -r1.2 path_finding.h
--- common/aicore/path_finding.h 2003/04/04 15:47:49 1.2
+++ common/aicore/path_finding.h 2003/07/16 22:54:55
@@ -125,8 +125,9 @@
* we won't be able to leave (at least alive).
*
* There are few other options in the path-finding, including "omniscience"
- * (if true, all tiles are assumed to be KNOWN) and "zoc_used" (if true, we
- * will consider restrictions imposed by zones of control upon our movements).
+ * (if true, all tiles are assumed to be KNOWN) and "get_zoc" callback (if
+ * not NULL, we will consider restrictions imposed upon our movements by
+ * zones of control).
*
*
* FORMULAE:
@@ -298,7 +299,6 @@
struct player *owner;
- bool zoc_used; /* Do we care about zones of control? */
bool omniscience; /* Do we care if the tile is visible? */
enum turn_mode turn_mode; /* See definitions. */
@@ -323,11 +323,20 @@
int (*get_EC) (int x, int y, enum known_type known,
struct pf_parameter * param);
+ /* Although the rules governing ZoC are universal, the amount of
+ * information available at server and client is different. To
+ * compensate for it, we might need to supply our own version
+ * of "common" is_my_zoc. Also AI might need to partially ignore
+ * ZoC for strategic planning purposes (take into account enemy cities
+ * but not units for example).
+ * If this callback is NULL, ZoC are ignored.*/
+ bool (*get_zoc) (struct player *pplayer, int x, int y);
+
/* If this callback is non-NULL and returns TRUE this position is
* dangerous. The unit will never end a turn at a dangerous
* position. Can be NULL. */
- bool(*is_pos_dangerous) (int x, int y, enum known_type,
- struct pf_parameter * param);
+ bool (*is_pos_dangerous) (int x, int y, enum known_type,
+ struct pf_parameter * param);
/* User provided data. Can be used to attach arbitrary information
* to the map. */
Index: common/aicore/pf_tools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/pf_tools.c,v
retrieving revision 1.2
diff -u -r1.2 pf_tools.c
--- common/aicore/pf_tools.c 2003/05/15 12:38:11 1.2
+++ common/aicore/pf_tools.c 2003/07/16 22:54:55
@@ -283,8 +283,12 @@
die("unknown move_type");
}
- parameter->zoc_used = (unit_type(punit)->move_type == LAND_MOVING
- && !unit_flag(punit, F_IGZOC));
+ if (unit_type(punit)->move_type == LAND_MOVING
+ && !unit_flag(punit, F_IGZOC)) {
+ parameter->get_zoc = is_my_zoc;
+ } else {
+ parameter->get_zoc = NULL;
+ }
if (unit_flag(punit, F_TRIREME)
&& base_trireme_loss_pct(unit_owner(punit)) > 0) {
@@ -323,7 +327,7 @@
die("Unsupported move_type");
}
- parameter->zoc_used = FALSE;
+ parameter->get_zoc = NULL;
if (unit_flag(punit, F_TRIREME)
&& base_trireme_loss_pct(unit_owner(punit)) > 0) {
[Freeciv-Dev] Re: (PR#3776) Goto sees ZOC but ignores it, Gregory Berkolaiko, 2003/07/16
[Freeciv-Dev] Re: (PR#3776) Goto sees ZOC but ignores it,
Gregory Berkolaiko <=
|
|