[Freeciv-Dev] (PR#6977) Wish List: Goto into unknown area
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=6977 >
Here is a patch. Please test.
I had no idea Raimar had already made a patch for this. Mine was made
completely separately but is almost identical in most parts.
TB = tile behavior
EC = extra cost
MC = move cost
1. First of all, a new client option (defaulting to true) is added.
Only if this option is enabled will goto into unknown be allowed.
2. If this is set, then the client allows unknown tiles to be
considered. Instead of TB_IGNORE they are TB_NORMAL.
3. (From Raimar's patch) Triremes consider unknown tiles to be
dangerous. Air units should consider them dangerous by default (since
an unknown tile will never have an airbase or city).
4. However this was insufficient by itself since unknown tiles have MC
0. The PF docs say to use EC to avoid unknown tiles but this is
impossible since MC always gets priority over EC. So I added a new
entry to the pf_parameter controlling the unknown move cost. And
instead of defaulting to 0 it defaults to a "very large value"
(currently 10 * SINGLE_MOVE).
5. So now assuming 10 * SINGLE_MOVE is sufficiently large, the path
chosen will be the one that requires the fewest unknown tiles. However
there is one issue that I can't see an easy way to fix it: a goto
through an unknown tile takes 10 turns (for a 1-move unit), and this is
reflected in the value shown on the mapview for the turns-to-get-there.
What should happen I think is the moves just shouldn't be drawn in this
case. But this means we have to know if the path goes through unknown.
This could be solved by following the path and checking (potentially
slow) or by setting an "infinite" EC for unknown tiles and then looking
at the final EC of the whole path (faster but potential for overflow).
In the meantime I just ignored the problem.
This patch may also improve the behavior of the non-omniscient AI.
-jason
Index: client/goto.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/goto.c,v
retrieving revision 1.87
diff -u -r1.87 goto.c
--- client/goto.c 25 Jun 2005 08:05:27 -0000 1.87
+++ client/goto.c 29 Jun 2005 22:57:34 -0000
@@ -350,10 +350,11 @@
struct pf_parameter *param)
{
if (known == TILE_UNKNOWN) {
- return TB_IGNORE;
- }
- if (is_non_allied_unit_tile(ptile, param->owner)
- || is_non_allied_city_tile(ptile, param->owner)) {
+ if (!goto_into_unknown) {
+ return TB_IGNORE;
+ }
+ } else if (is_non_allied_unit_tile(ptile, param->owner)
+ || is_non_allied_city_tile(ptile, param->owner)) {
/* Can attack but can't count on going through */
return TB_DONT_LEAVE;
}
@@ -369,7 +370,9 @@
struct pf_parameter *param)
{
if (known == TILE_UNKNOWN) {
- return TB_IGNORE;
+ if (!goto_into_unknown) {
+ return TB_IGNORE;
+ }
} else if (is_non_allied_city_tile(ptile, param->owner)) {
/* F_TRADE_ROUTE units can travel to, but not through, enemy cities.
* FIXME: F_HELP_WONDER units cannot. */
@@ -631,6 +634,22 @@
}
/**********************************************************************
+ PF callback to prohibit going into the unknown (conditionally). Also
+ makes sure we don't plan to attack anyone.
+***********************************************************************/
+static enum tile_behavior no_fights_or_unknown_goto(const struct tile *ptile,
+ enum known_type known,
+ struct pf_parameter *p)
+{
+ if (known == TILE_UNKNOWN && goto_into_unknown) {
+ /* Special case allowing goto into the unknown. */
+ return TB_NORMAL;
+ }
+
+ return no_fights_or_unknown(ptile, known, p);
+}
+
+/**********************************************************************
Fill the PF parameter with the correct client-goto values.
***********************************************************************/
static void fill_client_goto_parameter(struct unit *punit,
@@ -672,7 +691,7 @@
|| unit_flag(punit, F_HELP_WONDER)) {
parameter->get_TB = get_TB_caravan;
} else {
- parameter->get_TB = no_fights_or_unknown;
+ parameter->get_TB = no_fights_or_unknown_goto;
}
/* Note that in connect mode the "time" does not correspond to any actual
Index: client/options.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/options.c,v
retrieving revision 1.132
diff -u -r1.132 options.c
--- client/options.c 22 May 2005 09:53:12 -0000 1.132
+++ client/options.c 29 Jun 2005 22:57:34 -0000
@@ -64,6 +64,7 @@
bool auto_center_on_unit = TRUE;
bool auto_center_on_combat = FALSE;
bool wakeup_focus = TRUE;
+bool goto_into_unknown = TRUE;
bool center_when_popup_city = TRUE;
bool concise_city_production = FALSE;
bool auto_turn_done = FALSE;
@@ -189,6 +190,11 @@
N_("Set this option to have newly awoken units be "
"focused automatically."),
COC_INTERFACE),
+ GEN_BOOL_OPTION(goto_into_unknown, N_("Allow goto into the unknown"),
+ N_("If this option is set then goto will consider moving "
+ "into unknown tiles. If not, then goto routes will "
+ "detour around or be blocked by unknown tiles."),
+ COC_INTERFACE),
GEN_BOOL_OPTION(center_when_popup_city, N_("Center map when Popup city"),
N_("If this option is set then when a city dialog is "
"popped up, the city will be centered automatically."),
Index: client/options.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/options.h,v
retrieving revision 1.53
diff -u -r1.53 options.h
--- client/options.h 22 May 2005 09:53:12 -0000 1.53
+++ client/options.h 29 Jun 2005 22:57:34 -0000
@@ -38,6 +38,7 @@
extern bool auto_center_on_unit;
extern bool auto_center_on_combat;
extern bool wakeup_focus;
+extern bool goto_into_unknown;
extern bool center_when_popup_city;
extern bool concise_city_production;
extern bool auto_turn_done;
Index: common/aicore/path_finding.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/path_finding.c,v
retrieving revision 1.32
diff -u -r1.32 path_finding.c
--- common/aicore/path_finding.c 25 Jun 2005 08:05:27 -0000 1.32
+++ common/aicore/path_finding.c 29 Jun 2005 22:57:35 -0000
@@ -27,9 +27,6 @@
/* For explanations on how to use this module, see path_finding.h */
-/* Default move cost into the unknown (see path_finding.h) */
-#define MOVE_COST_UNKNOWN 0
-
#define INITIAL_QUEUE_SIZE 100
/* Since speed is quite important to us and alloccation of large arrays is
@@ -392,7 +389,7 @@
/* Evaluate the cost of the move */
if (node1->node_known_type == TILE_UNKNOWN) {
- cost = MOVE_COST_UNKNOWN;
+ cost = pf_map->params->unknown_MC;
} else {
cost = pf_map->params->get_MC(pf_map->tile, dir, tile1,
pf_map->params);
@@ -965,7 +962,7 @@
/* Evaluate the cost of the move */
if (node1->node_known_type == TILE_UNKNOWN) {
- cost = MOVE_COST_UNKNOWN;
+ cost = pf_map->params->unknown_MC;
} else {
cost = pf_map->params->get_MC(pf_map->tile, dir, tile1,
pf_map->params);
Index: common/aicore/path_finding.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/path_finding.h,v
retrieving revision 1.12
diff -u -r1.12 path_finding.h
--- common/aicore/path_finding.h 25 Jun 2005 08:05:27 -0000 1.12
+++ common/aicore/path_finding.h 29 Jun 2005 22:57:36 -0000
@@ -42,9 +42,11 @@
* path: a list of steps which leads from the start to the end
*
* move cost (MC): move cost of a _single_ step. MC is always >= 0.
- * Note that the MC of a step is taken to be 0 if the target is
- * unknown. The idea is that the user can set the unknown move cost
- * via EC callback.
+ * [The parameter can specify what the MC of a step into the unknown is
+ * to be (this is a constant for each map). This defaults to a
+ * very large value meaning unknown tiles are avoided. It's also
+ * possible to use 0 here and use TB or EC to control movement through
+ * unknown tiles.]
*
* extra cost (EC): extra cost of a _single_ tile. EC is always >= 0.
* The intended meaning for EC is "how much we want to avoid this tile",
@@ -230,8 +232,8 @@
* path_finding_tools or a mix of these.
*
* Hints:
- * 1. Since MC into unknown is 0, it is useful to limit the expansion of
- * unknown tiles with a get_TB callback.
+ * 1. It is useful to limit the expansion of unknown tiles with a get_TB
+ * callback. In this case you might set the unknown_MC to be 0.
* 2. If there are two paths of the same cost to a tile (x,y), you are
* not guaranteed to get the one with the least steps in it. If you care,
* specifying EC to be 1 will do the job.
@@ -330,6 +332,7 @@
* implementation of the callback. */
int (*get_MC) (const struct tile *from_tile, enum direction8 dir,
const struct tile *to_tile, struct pf_parameter * param);
+ int unknown_MC; /* Move cost into unknown - very large by default */
/* Callback which determines the behavior of a tile. If NULL
* TB_NORMAL is assumed. It can be assumed that the implementation
Index: common/aicore/pf_tools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/pf_tools.c,v
retrieving revision 1.33
diff -u -r1.33 pf_tools.c
--- common/aicore/pf_tools.c 25 Jun 2005 08:05:27 -0000 1.33
+++ common/aicore/pf_tools.c 29 Jun 2005 22:57:36 -0000
@@ -514,6 +514,11 @@
enum known_type known,
struct pf_parameter *param)
{
+ /* Assume that unknown tiles are unsafe. */
+ if (known == TILE_UNKNOWN) {
+ return TRUE;
+ }
+
/* We test TER_UNSAFE even though under the current ruleset there is no
* way for a trireme to be on a TER_UNSAFE tile. */
/* Unsafe or unsafe-ocean tiles without cities are dangerous. */
@@ -772,6 +777,7 @@
struct unit *punit)
{
parameter->turn_mode = TM_CAPPED;
+ parameter->unknown_MC = 10 * SINGLE_MOVE;
parameter->get_TB = NULL;
parameter->get_EC = NULL;
parameter->is_pos_dangerous = NULL;
|
|