<URL: http://bugs.freeciv.org/Ticket/Display.html?id=39852 >
Daniel Markstedt wrote: > I'm generally for freedom. If the player wants to goto their stealth > fighter to certain death, the gui should allow them to do it. It's not > uncommon to make suicide attacks with air units anyway. Let's leave > this behavior as it is. > ... > The issue here is that the pathfinding code believes this goto can be > completed, while the poor stealth fighter in fact only gets halfway > and crashes. It must somehow believe the air unit will become refuled > just because a friendly city is nearby. This is IMHO in the scope of > this ticket. > These are incompatible goals. Here's the coding compromise: * for AI, allow 1/2 round trip only when starting at fueling base. * for user, allow up to 1/2 the remaining fuel, no matter where we're starting. This allows a user to set waypoints to control the path. But at the final step, they won't necessarily be able to land. int have = get_moves_left_initially(param); if (have >= moves * 2 && (is_possible_base_fuel(param->start_tile, param) || !param->owner->ai.control)) { /* has enough fuel for round trip. */ return FALSE; } Found an existing static function for determining remaining moves in path_finding.c -- made it accessible. There are (at least) 3 different ways being used to calculate this; perhaps this narrows down the solution. > Certainly not for 2.1. It would be a useful feature if city-hopping > could be done automagically, but as you say it can be done with > waypoints. > Found airgoto.c make_list_of_refuel_points() -- it just doesn't seem to be used (or work) consistently. (heavy sigh) Anyway, I just checked this in to S2_1, and will handle the other branches only after verification.... Committed S2_1 revision 13944.
Index: common/aicore/path_finding.h =================================================================== --- common/aicore/path_finding.h (revision 13943) +++ common/aicore/path_finding.h (working copy) @@ -397,7 +397,7 @@ /* The map itself. Opaque type. */ struct pf_map; -/* ==================== Functions =================================== */ +/* ==================== Map/Path Functions ========================== */ /* Returns a map which can be used to query for paths or to iterate * over all paths. Does not perform any computations itself, just sets @@ -449,4 +449,8 @@ /* Return the current parameters for the given map. */ struct pf_parameter *pf_get_parameter(struct pf_map *map); +/* ==================== Parameter Functions ========================= */ + +int get_moves_left_initially(const struct pf_parameter *param); + #endif Index: common/aicore/pf_tools.c =================================================================== --- common/aicore/pf_tools.c (revision 13943) +++ common/aicore/pf_tools.c (working copy) @@ -529,7 +529,19 @@ && (terrain_has_flag(ptile->terrain, TER_UNSAFE) || (is_ocean(ptile->terrain) && !is_safe_ocean(ptile)))); } + /**************************************************************************** + Refueling base for air units. +****************************************************************************/ +static bool is_possible_base_fuel(const struct tile *ptile, + struct pf_parameter *param) +{ + /* All airbases are considered possible, simply attack enemies. */ + return (is_allied_city_tile(ptile, param->owner) + || tile_has_special(ptile, S_AIRBASE)); +} + +/**************************************************************************** Position-dangerous callback for air units. ****************************************************************************/ static bool is_pos_dangerous_fuel(const struct tile *ptile, @@ -537,29 +549,30 @@ struct pf_parameter *param) { int moves = SINGLE_MOVE * real_map_distance(param->start_tile, ptile); - int fuel = param->move_rate * param->fuel_left_initially; + int have = get_moves_left_initially(param); - if (fuel < moves) { + if (have < moves) { /* not enough fuel. */ return TRUE; } - if (fuel >= moves * 2) { + if (have >= moves * 2 + && (is_possible_base_fuel(param->start_tile, param) + || !param->owner->ai.control)) { /* has enough fuel for round trip. */ return FALSE; } - if (fuel >= moves - && (is_allied_city_tile(ptile, param->owner) - || tile_has_special(ptile, S_AIRBASE))) { - /* All airbases are considered non-dangerous, although non-allied ones - * are inaccessible. */ + if (TILE_UNKNOWN != known + && (is_possible_base_fuel(ptile, param) + || is_enemy_city_tile(ptile, param->owner))) { + /* allow attacks, even suicidal ones */ return FALSE; } - if (is_enemy_unit_tile(ptile, param->owner) - || is_enemy_city_tile(ptile, param->owner)) { - /* allow attacks, even suicidal ones */ + if (TILE_KNOWN == known + && is_enemy_unit_tile(ptile, param->owner)) { + /* don't reveal unknown units */ return FALSE; } Index: common/aicore/path_finding.c =================================================================== --- common/aicore/path_finding.c (revision 13943) +++ common/aicore/path_finding.c (working copy) @@ -121,7 +121,7 @@ turn. Thus the rest of the PF code doesn't actually know that the unit has fuel, it just thinks it has that many more MP. ****************************************************************************/ -static int get_moves_left_initially(const struct pf_parameter *param) +int get_moves_left_initially(const struct pf_parameter *param) { return (param->moves_left_initially + (param->fuel_left_initially - 1) * param->move_rate);
_______________________________________________ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev