[Freeciv-Dev] (PR#13277) air units, fuel, and pathfinding (PF) / goto
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13277 >
> [jdorje - Thu Jun 16 20:06:32 2005]:
>
> Currently PF doesn't handle fuel. It handles air units but assumes that
> fuel == 1 for all units, so all non-airbase positions are dangerous.
> Basically this means that bombers aren't as efficient as they should be.
>
> This can be fixed. However it won't be especially easy. There's
> probably already a ticket for it actually, but I sure can't find it.
>
> I believe the best suggestion so far is to fake it. Basically if you
> have a unit with fuel F1, and move rate M1 you transform it into a new
> unit with fuel 1 and move rate M2=F1*M1. Now you get the optimal path
> using the same algorithm as before (that works with fuel 1) but certain
> characteristics of the path are wrong. For instance the turns and MP
> for each position on the path are incorrect, so you have to do a reverse
> of the transformation at the end to provide the correct values in each
node.
Here is a preliminary patch to do this. Air is supported in the core
pathfinding code by a move_turns parameter (which for air units is equal
to the amount of fuel). The caller is expected to adjust the move_rate
and moves_left_initially by this value included in the pf_parameter).
The core PF code then adjusts the returned positions based on this value
so that the correct number of turns and moves left are given back.
It's a little buggy however. It won't work with waypoints since the
start_moves_left isn't carried over properly. Also for some reason the
number of turns isn't being shown properly.
I think the solution to all this is to move the fuel entirely into the
core PF.
- The pf_parameter gets a fuel_left_initially. move_turns is renamed
simply as fuel.
- Multiplication of the turns is done internally in path_finding.c.
- Then the client/goto.c code will also have to know about fuel,
tracking the units of fuel available at the start and end of each path
(just like moves left is already tracked).
-jason
Index: data/default/units.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/units.ruleset,v
retrieving revision 1.68
diff -u -r1.68 units.ruleset
--- data/default/units.ruleset 2 May 2005 08:45:21 -0000 1.68
+++ data/default/units.ruleset 17 Jun 2005 21:49:02 -0000
@@ -966,7 +966,7 @@
[unit_fighter]
name = _("Fighter")
move_type = "Air"
-tech_req = "Flight"
+tech_req = "None"
obsolete_by = "Stealth Fighter"
graphic = "u.fighter"
graphic_alt = "-"
@@ -974,7 +974,7 @@
sound_move_alt = "m_generic"
sound_fight = "f_fighter"
sound_fight_alt = "f_generic"
-build_cost = 60
+build_cost = 1
pop_cost = 0
attack = 4
defense = 3
@@ -994,7 +994,7 @@
[unit_bomber]
name = _("Bomber")
move_type = "Air"
-tech_req = "Advanced Flight"
+tech_req = "None"
obsolete_by = "Stealth Bomber"
graphic = "u.bomber"
graphic_alt = "-"
@@ -1002,16 +1002,16 @@
sound_move_alt = "m_generic"
sound_fight = "f_bomber"
sound_fight_alt = "f_generic"
-build_cost = 120
+build_cost = 1
pop_cost = 0
attack = 12
defense = 1
hitpoints = 20
firepower = 2
-move_rate = 8
+move_rate = 2
vision_range = 2
transport_cap = 0
-fuel = 2
+fuel = 8
uk_happy = 1
uk_shield = 1
uk_food = 0
@@ -1064,7 +1064,7 @@
sound_move_alt = "m_generic"
sound_fight = "f_stealth_fighter"
sound_fight_alt = "f_generic"
-build_cost = 80
+build_cost = 1
pop_cost = 0
attack = 8
defense = 4
Index: common/aicore/path_finding.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/path_finding.c,v
retrieving revision 1.31
diff -u -r1.31 path_finding.c
--- common/aicore/path_finding.c 2 May 2005 15:42:53 -0000 1.31
+++ common/aicore/path_finding.c 17 Jun 2005 21:56:32 -0000
@@ -535,8 +535,14 @@
+ pf_map->params->moves_left_initially;
if (pf_map->params->turn_mode == TM_BEST_TIME ||
pf_map->params->turn_mode == TM_WORST_TIME) {
+ int base_mr = pf_map->params->move_rate / pf_map->params->move_turns;
+
pos->turn = get_turn(pf_map, node->cost);
pos->moves_left = get_moves_left(pf_map, node->cost);
+
+ pos->turn *= pf_map->params->move_turns;
+ pos->turn += pos->moves_left / base_mr;
+ pos->moves_left %= base_mr;
} else if (pf_map->params->turn_mode == TM_NONE ||
pf_map->params->turn_mode == TM_CAPPED) {
pos->turn = -1;
Index: common/aicore/path_finding.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/path_finding.h,v
retrieving revision 1.11
diff -u -r1.11 path_finding.h
--- common/aicore/path_finding.h 10 Jan 2005 03:24:16 -0000 1.11
+++ common/aicore/path_finding.h 17 Jun 2005 21:56:32 -0000
@@ -296,6 +296,8 @@
struct tile *start_tile; /* Initial position */
int moves_left_initially;
int move_rate; /* Move rate of the virtual unit */
+ int move_turns; /* How many turns should be considered as
+ * one (equal to fuel for air units). */
struct player *owner;
Index: common/aicore/pf_tools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/pf_tools.c,v
retrieving revision 1.32
diff -u -r1.32 pf_tools.c
--- common/aicore/pf_tools.c 23 Apr 2005 17:40:28 -0000 1.32
+++ common/aicore/pf_tools.c 17 Jun 2005 21:56:32 -0000
@@ -771,6 +771,8 @@
static void pft_fill_unit_default_parameter(struct pf_parameter *parameter,
struct unit *punit)
{
+ int mr = unit_move_rate(punit);
+
parameter->turn_mode = TM_CAPPED;
parameter->get_TB = NULL;
parameter->get_EC = NULL;
@@ -781,7 +783,16 @@
parameter->start_tile = punit->tile;
parameter->moves_left_initially = punit->moves_left;
- parameter->move_rate = unit_move_rate(punit);
+ if (is_air_unit(punit)) {
+ if (punit->fuel > 1) {
+ parameter->moves_left_initially += mr * (punit->fuel - 1);
+ }
+ parameter->move_turns = unit_type(punit)->fuel;
+ parameter->move_rate = mr * parameter->move_turns;
+ } else {
+ parameter->move_rate = mr;
+ parameter->move_turns = 1;
+ }
parameter->owner = unit_owner(punit);
parameter->unit_flags = unit_type(punit)->flags;
Index: client/goto.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/goto.c,v
retrieving revision 1.86
diff -u -r1.86 goto.c
--- client/goto.c 28 May 2005 21:24:00 -0000 1.86
+++ client/goto.c 17 Jun 2005 21:56:33 -0000
@@ -248,7 +248,7 @@
struct unit *punit = find_unit_by_id(goto_map.unit_id);
p->start_tile = punit->tile;
- p->start_moves_left = punit->moves_left;
+ p->start_moves_left = parameter.moves_left_initially;
} else {
struct part *prev = &goto_map.parts[goto_map.num_parts - 2];
@@ -260,7 +260,6 @@
p->end_tile = p->start_tile;
p->time = 0;
parameter.start_tile = p->start_tile;
- parameter.moves_left_initially = p->start_moves_left;
p->map = pf_create_map(¶meter);
}
|
|