]> git.pond.sub.org Git - empserver/log
empserver
13 years agoClean up move_ground()'s parsing of DIR_MAP
Markus Armbruster [Sun, 10 Apr 2011 16:09:16 +0000 (18:09 +0200)]
Clean up move_ground()'s parsing of DIR_MAP

Split with parse() and pass first two arguments instead of the raw
tail to the map() callback.  Advantages:

* Consistent with do_unit_move().

* Does the right thing when the tail is just spaces.  Before, the
  spaces got passed to the map() callback, which complained about
  syntax.  Now, they are ignored.  This is what the commit I just
  reverted tried to fix.

* Works better when the tail splits into more than two arguments.
  Except for explore_map(), which ignores the argument(s), the map()
  callbacks use display_region_map(), which split the tail at the
  first space, and complained about any spaces in the second part.
  Now, display_region_map() takes two argument strings instead of a
  single, unsplit argument string, and extra arguments get silently
  ignored, as usual.

13 years agoRevert "(move_ground): Passed junk to map callback when 'm' sub-command"
Markus Armbruster [Sun, 10 Apr 2011 12:51:03 +0000 (14:51 +0200)]
Revert "(move_ground): Passed junk to map callback when 'm' sub-command"

It ignores all embedded space, not just trailing space after 'm'.

This reverts commit f65b255d1871ea0a1fa87d6d87c527566e108b87.

13 years agoCollapse duplicated code in draw_map()
Markus Armbruster [Sun, 10 Apr 2011 08:16:59 +0000 (10:16 +0200)]
Collapse duplicated code in draw_map()

One loop for maps and one for bmaps suffice.  Before, we had two
similar ones for each.

13 years agoFix map drawing commands to report bad unit arguments
Markus Armbruster [Sun, 10 Apr 2011 07:14:29 +0000 (09:14 +0200)]
Fix map drawing commands to report bad unit arguments

Before, they failed without explanation when they interpreted the
argument as unit number, but the player didn't own that unit.

13 years agoChange unit_map() not to use RET_OK and RET_FAIL as return values
Markus Armbruster [Sun, 10 Apr 2011 07:11:20 +0000 (09:11 +0200)]
Change unit_map() not to use RET_OK and RET_FAIL as return values

Returning 0 and -1 is simpler.

13 years agoClean up bmap commands' flags argument
Markus Armbruster [Sun, 10 Apr 2011 05:43:04 +0000 (07:43 +0200)]
Clean up bmap commands' flags argument

parse_map_flags() silently truncates map flags after the first 't' or
'r'.  This makes it accept arguments "true" and "revert".  However, it
also breaks the perfectly sensible argument "ts", which should show
ships just like "st", but doesn't.

info bmap & friends document arguments "true" and "revert", and also
suggest flags 't' and 'r'.  What a mess.

Make argument "revert" a special case.  Deprecate flag 'r', and clean
up truncation there.

Don't truncate after flag 't'.  If any bad flags follow, ignore
everything after 't', but deprecate that usage.

13 years agoFactor parse_map_flags() out of do_map()
Markus Armbruster [Sun, 10 Apr 2011 05:27:23 +0000 (07:27 +0200)]
Factor parse_map_flags() out of do_map()

13 years agoFold draw_map() parameter bmap into map_flags
Markus Armbruster [Sun, 10 Apr 2011 05:18:53 +0000 (07:18 +0200)]
Fold draw_map() parameter bmap into map_flags

No functional change.

13 years agoTweak info on movement commands' map drawing sub-commands
Markus Armbruster [Sat, 9 Apr 2011 18:49:35 +0000 (20:49 +0200)]
Tweak info on movement commands' map drawing sub-commands

13 years agoFail map drawing command when player doesn't confirm bmap revert
Markus Armbruster [Sat, 9 Apr 2011 18:39:34 +0000 (20:39 +0200)]
Fail map drawing command when player doesn't confirm bmap revert

Doesn't affect mapping at movement prompts (navigate, march, move,
test and transport), because the failure is ignored there.

13 years agoDon't show a map on bmap revert
Markus Armbruster [Sat, 9 Apr 2011 18:34:22 +0000 (20:34 +0200)]
Don't show a map on bmap revert

Before, it showed a map, but only when the player confirmed the
revert.

13 years agoClean up map info pages a bit
Markus Armbruster [Sat, 9 Apr 2011 18:19:15 +0000 (20:19 +0200)]
Clean up map info pages a bit

Drop .SY for map commands other than the one documented by the info
page.

Use the page's command to discuss arguments "revert" and "true", not
"bmap".

Clarify flags argument.

13 years agoDrop useless checks for player->aborted in draw_map()
Markus Armbruster [Sat, 9 Apr 2011 13:36:40 +0000 (15:36 +0200)]
Drop useless checks for player->aborted in draw_map()

player->aborted gets set when we get an interrupt or EOF cookie from
the player, when update or shutdown abort commands, and when we abort
an attack (not relevant here).

The checks are useless: player interrupt and EOF are checked
elsewhere, and update/shutdown can run only when we yield the
processor, which we never do (output doesn't yield because C_MOD is
set).

13 years agoDrop potentially misleading build and radar error messages
Markus Armbruster [Sat, 9 Apr 2011 13:36:21 +0000 (15:36 +0200)]
Drop potentially misleading build and radar error messages

buil() complains about the argument when snxtsct() fails.  Misleading
when the argument is fine, but snxtsct() fails due to bad conditional
argument.

Same for radar() with snxtitem().

13 years agoRemove disabled command cede
Markus Armbruster [Sat, 9 Apr 2011 13:31:04 +0000 (15:31 +0200)]
Remove disabled command cede

It misuses snxtsct() and snxtitem() to find out whether the first
argument looks like sectors or like ships, which doesn't work with a
bad conditional argument.

Not worth fixing now; it's been disabled since 4.0.1, and broken at
least since commit 2fc1e74a (v4.3.0) broke its sector/ship
disambiguation via third argument.

13 years agoFix do_map()'s misuse of snxtsct() for testing argument syntax
Markus Armbruster [Sat, 9 Apr 2011 12:57:42 +0000 (14:57 +0200)]
Fix do_map()'s misuse of snxtsct() for testing argument syntax

It assumes snxtsct() fails only when the argument can't be parsed.  It
can also fail when the condition argument has errors.  `map # ?xxx'
first complains about xxx, then maps around ship#0.  Broken since
Chainsaw 2 introduced smap, pmap and lmap.

Use sarg_type() to recognize sectors vs. unit argument.  `map # ?xxx'
now fails as it should.

Subtle side effect: do_map() no longer prompts for argument "",
because snxtsct() is now guarded by sarg_type().  Impact on callers:

* display_region_map() is not affected, because it never passes "".

* map() passes on "" arguments.  Change it to prompt in that case.
  Consistent with how other commands behave.  No functional change.

* do_unit_move() passes on "" arguments.  Keep it that way.  This
  changes navigate and march sub-commands 'M' and 'B' not to prompt
  for "" arguments, which is consistent with sub-command 'm' of move,
  test and transport.

13 years agoMake map drawing commands fail on bad flags
Markus Armbruster [Sat, 9 Apr 2011 08:39:12 +0000 (10:39 +0200)]
Make map drawing commands fail on bad flags

Also affects mapping at movement prompts of navigate, march, move,
test, transport.

13 years agoMove function declarations for maps.c from prototypes.h to map.h
Markus Armbruster [Sat, 9 Apr 2011 07:28:58 +0000 (09:28 +0200)]
Move function declarations for maps.c from prototypes.h to map.h

13 years agoMove map flags from map.h to maps.c, and reorder
Markus Armbruster [Sat, 9 Apr 2011 06:56:01 +0000 (08:56 +0200)]
Move map flags from map.h to maps.c, and reorder

Not useful elsewhere.  Since I'm touching them anyway, put them in the
usual ship, plane, land, nuke order.

13 years agoRemove misleading comment on MAP_PLANE & friends
Markus Armbruster [Sat, 9 Apr 2011 06:40:33 +0000 (08:40 +0200)]
Remove misleading comment on MAP_PLANE & friends

ef_unit_list doesn't exist.  Order doesn't matter, priority is defined
by draw_map()'s ef_unit_map[].

This reverts commit 9e75e5e0094a518ba7445b4fd278aca09c6830c0.

13 years agoDrop "xdump ver" deprecated in 4.3.12
Markus Armbruster [Sat, 9 Apr 2011 06:01:58 +0000 (08:01 +0200)]
Drop "xdump ver" deprecated in 4.3.12

13 years agoinfo xdump still has long gone pseudo-table ver, remove
Markus Armbruster [Sat, 9 Apr 2011 05:59:19 +0000 (07:59 +0200)]
info xdump still has long gone pseudo-table ver, remove

Missed in commit da8a1dae, v4.3.12

13 years agoMove xdmeta() back to commands/xdump.c, internal linkage
Markus Armbruster [Sat, 9 Apr 2011 05:39:58 +0000 (07:39 +0200)]
Move xdmeta() back to commands/xdump.c, internal linkage

Partially revert commit 4c746b5e.

13 years agoSimplify satmap() with snxtitem_use_condarg(), snxtsct_use_condarg()
Markus Armbruster [Fri, 8 Apr 2011 19:15:05 +0000 (21:15 +0200)]
Simplify satmap() with snxtitem_use_condarg(), snxtsct_use_condarg()

13 years agoFactor snxtsct_use_condarg() out of snxtsct()
Markus Armbruster [Fri, 8 Apr 2011 19:13:07 +0000 (21:13 +0200)]
Factor snxtsct_use_condarg() out of snxtsct()

13 years agoFactor snxtitem_use_condarg() out of snxtitem()
Markus Armbruster [Fri, 8 Apr 2011 19:11:34 +0000 (21:11 +0200)]
Factor snxtitem_use_condarg() out of snxtitem()

13 years agoFix satellite to fail on bad conditional
Markus Armbruster [Fri, 8 Apr 2011 19:06:56 +0000 (21:06 +0200)]
Fix satellite to fail on bad conditional

snxtsct() and snxtitem() fail when the condition argument is bad.
satmap() didn't check for failure.  Due to the way snxtsct() and
snxtitem() work, bad condition arguments were reported and otherwise
ignored.

13 years agoCollect nstr_item, nstr_sect function declarations in nsc.h
Markus Armbruster [Fri, 8 Apr 2011 18:42:16 +0000 (20:42 +0200)]
Collect nstr_item, nstr_sect function declarations in nsc.h

Moved from prototypes.h.

13 years agoMove xysize_range(), xydist_range() to xy.c and xy.h
Markus Armbruster [Fri, 8 Apr 2011 18:38:03 +0000 (20:38 +0200)]
Move xysize_range(), xydist_range() to xy.c and xy.h

Moved from snxtsct.c and prototypes.h next to the other struct range
functions.

13 years agoFix journal.c boilerplate comment
Markus Armbruster [Mon, 4 Apr 2011 17:58:47 +0000 (19:58 +0200)]
Fix journal.c boilerplate comment

13 years agoNew journal event "output"
Markus Armbruster [Mon, 4 Apr 2011 06:09:25 +0000 (08:09 +0200)]
New journal event "output"

Redundant information, but incredibly useful when you want to figure
out what happened without a (still nonexistent) journal replay tool.
The redundancy could help making a journal replay tool more robust.

To enable, set econfig key keep_journal to at least 2.  Output events
are *not* flushed to disk immediately.

13 years agoFix journal not to truncate long lines
Markus Armbruster [Mon, 4 Apr 2011 06:00:08 +0000 (08:00 +0200)]
Fix journal not to truncate long lines

Could happen only for input events.

13 years agoEscape '\\' in journal, but not '\t'
Markus Armbruster [Mon, 4 Apr 2011 05:59:25 +0000 (07:59 +0200)]
Escape '\\' in journal, but not '\t'

13 years agoJournal login phase input, too
Markus Armbruster [Mon, 4 Apr 2011 05:58:08 +0000 (07:58 +0200)]
Journal login phase input, too

13 years agoNew journal event "command"
Markus Armbruster [Sun, 3 Apr 2011 06:27:30 +0000 (08:27 +0200)]
New journal event "command"

Redundant information.  Allows making sense of input without context.
The redundancy could help making a journal replay tool more robust.

13 years agoClean up superfluous include of queue.h in land.h, ship.h
Markus Armbruster [Sun, 3 Apr 2011 09:20:06 +0000 (11:20 +0200)]
Clean up superfluous include of queue.h in land.h, ship.h

13 years agoClean up superfluous include of nsc.h in prototypes.h
Markus Armbruster [Sun, 3 Apr 2011 08:41:10 +0000 (10:41 +0200)]
Clean up superfluous include of nsc.h in prototypes.h

13 years agoClean up superfluous include of news.h in empobj.h
Markus Armbruster [Sun, 3 Apr 2011 08:36:46 +0000 (10:36 +0200)]
Clean up superfluous include of news.h in empobj.h

Missed in commit 0ba61f17, v4.3.24.

13 years agoDisable BRIDGETOWERS by default
Markus Armbruster [Sat, 2 Apr 2011 12:41:09 +0000 (14:41 +0200)]
Disable BRIDGETOWERS by default

A deity can easily break BRIDGETOWERS by reducing etu_per_update
without compensating customization of buil_tower_bh,
rollover_avail_max or bridge span maxpop.

Document the issue in output of pconfig (which is installed as
$prefix/etc/empire/econfig).

To increase the chance deities actually read the documentation,
disable BRIDGETOWERS.

13 years agoReduce bridge tower materials from 400 to 300 hcms.
Markus Armbruster [Sat, 2 Apr 2011 12:20:54 +0000 (14:20 +0200)]
Reduce bridge tower materials from 400 to 300 hcms.

Bridge spans have been unable to produce enough avail for a tower with
default game configuration since we reduced their maximum population
in commit 6bbd7ffd, v4.3.6.  This commit reduces required avail from
160 to 120, fixing the stock game: 100 civilians and 100 uws can make
that much in a 60 ETU update.

13 years agoFix stop orders to expire even when the country is broke
Markus Armbruster [Tue, 29 Mar 2011 18:09:56 +0000 (20:09 +0200)]
Fix stop orders to expire even when the country is broke

Broken in commit 8da88626, v4.3.8.

13 years agoFix march and navigate not to interpret coordinates as path
Markus Armbruster [Sun, 27 Mar 2011 15:55:35 +0000 (17:55 +0200)]
Fix march and navigate not to interpret coordinates as path

Destination arguments can be a path or sector coordinates.
do_unit_move() passes the argument buffer to unit_path() to convert
coordinates to a path.  If unit_path() fails, do_unit_move() still
interprets the argument as path.

This is correct when unit_path() fails because the argument is not
coordinates.  But it can also fail when it is coordinates, namely when
the destination isn't reachable, when the path to it is too long, or
when the ships or land units aren't together.  Then do_unit_move()
interprets coordinates as path, and rejects them with "Legal
directions are:".

Except when a land unit's destination read from a march prompt isn't
reachable, because then unit_path() empties the argument buffer that
do_unit_move() uses.

Change unit_path() to succeed when the argument is not coordinates.
Make do_unit_move() discard the argument when unit_path() fails,
i.e. when it is bad coordinates.  unit_path() emptying the argument no
longer has an effect, drop it.

13 years agoClean up path finding in perform_mission_bomb()
Markus Armbruster [Sun, 27 Mar 2011 08:08:16 +0000 (10:08 +0200)]
Clean up path finding in perform_mission_bomb()

Support missions up to 1023 sectors away from the airfield, up from
99.

Don't bother to call mapdist() for distance to target, just use the
path length.

13 years agoClean up path finding in nav_ship()
Markus Armbruster [Sun, 27 Mar 2011 08:02:36 +0000 (10:02 +0200)]
Clean up path finding in nav_ship()

Destinations are no longer treated as unreachable when the best path
is longer than 99 characters.  Instead, consider up to 1023 characters
of the best path.

13 years agoClean up path finding in getpath()
Markus Armbruster [Sun, 27 Mar 2011 06:44:30 +0000 (08:44 +0200)]
Clean up path finding in getpath()

Don't claim the destination sector is unreachable when the best path
is longer than 99 characters or the complete path is longer than 1023
characters.  Instead, report that the path is too long when the total
path is longer than 1023 characters.

13 years agoRemove p_mode, use MOB_FLY and MOB_SAIL instead
Markus Armbruster [Sun, 27 Mar 2011 06:29:50 +0000 (08:29 +0200)]
Remove p_mode, use MOB_FLY and MOB_SAIL instead

13 years agoClean up path finding in unit_sub()
Markus Armbruster [Sat, 26 Mar 2011 13:34:53 +0000 (14:34 +0100)]
Clean up path finding in unit_sub()

Don't claim the destination sector is unreachable when the best path
is longer than 1023 characters for land units or 99 characters for
ships.  Instead, report that the path is too long.  Up the limit for
ships to 1023 characters.

13 years agoClean up path finding in move_ground()
Markus Armbruster [Sat, 26 Mar 2011 12:15:05 +0000 (13:15 +0100)]
Clean up path finding in move_ground()

Don't claim the destination sector is unreachable when the best path
is longer than 1023 characters.  Instead, report that the path is too
long.

13 years agoClean up path finding in path()
Markus Armbruster [Sat, 26 Mar 2011 07:15:08 +0000 (08:15 +0100)]
Clean up path finding in path()

Don't claim the destination sector is unreachable when the best path
is longer than 1023 characters.  Instead, report that the path is too
long.

13 years agoClean up path finding in best()
Markus Armbruster [Sat, 26 Mar 2011 07:10:30 +0000 (08:10 +0100)]
Clean up path finding in best()

Handle paths longer than 1023 characters sensibly: show them with
"..." appended.

13 years agoInline BestShipPath(), BestAirPath() glue
Markus Armbruster [Sat, 26 Mar 2011 07:03:19 +0000 (08:03 +0100)]
Inline BestShipPath(), BestAirPath() glue

Following commits will simplify the resulting code.

13 years agoInline BestLandPath(), BestDistPath() glue
Markus Armbruster [Sat, 26 Mar 2011 06:51:52 +0000 (07:51 +0100)]
Inline BestLandPath(), BestDistPath() glue

Following commits will simplify the resulting code.

13 years agoUse path_find() directly in sorde()
Markus Armbruster [Mon, 21 Mar 2011 19:45:04 +0000 (20:45 +0100)]
Use path_find() directly in sorde()

Don't compute the distance from the path, use the path cost.  The
actual path is no longer needed, and we can use path_find() instead of
BestShipPath().

Destinations are no longer treated as unreachable when the best path
is longer than 1023 characters.

13 years agoSimplify eta_calc(): drop pointer parameter, return value instead
Markus Armbruster [Mon, 21 Mar 2011 19:43:21 +0000 (20:43 +0100)]
Simplify eta_calc(): drop pointer parameter, return value instead

13 years agoSimplify eta_calc(): let caller compute path length
Markus Armbruster [Mon, 21 Mar 2011 19:42:37 +0000 (20:42 +0100)]
Simplify eta_calc(): let caller compute path length

13 years agoOptimize s_commod()'s harbor check for embarked land units
Markus Armbruster [Mon, 21 Mar 2011 19:39:47 +0000 (20:39 +0100)]
Optimize s_commod()'s harbor check for embarked land units

13 years agoUse path_find() directly where only cost is needed
Markus Armbruster [Mon, 21 Mar 2011 19:26:02 +0000 (20:26 +0100)]
Use path_find() directly where only cost is needed

dist(), att_reacting_units() and s_commod() are only interested in
cost, not the actual path.  BestLandPath() and BestDistPath() compute
both cost and path.  Use path_find() directly instead.

Destinations are no longer treated as unreachable when the best path
is longer than 1023 characters.

13 years agoUse the new path finder for sea & air, drop bestownedpath()
Markus Armbruster [Tue, 22 Feb 2011 06:18:41 +0000 (07:18 +0100)]
Use the new path finder for sea & air, drop bestownedpath()

bestownedpath() is a rather simple-minded breadth-first search.  It's
slower than the new path finder, and maintaining it in addition to the
new path finder makes no sense.

13 years agoCompute distribution paths center by center
Markus Armbruster [Mon, 21 Feb 2011 22:13:07 +0000 (23:13 +0100)]
Compute distribution paths center by center

This way, we compute all distribution paths from the same center in
one go, and thus fully exploit the fast multiple paths from same
source capability of Dijkstra's algorithm.

Sorting by dist center increases the average length of runs from 4.5
to 73 for my continental test case, and from 3 to 10 for my island
test case.

Compared to the commit before the previous one, distribution path
assembly runs more than 40 times faster for my continental test case,
and more than 5 times faster for my island test case.

The new path finder now runs my continental test case more than 30
times faster than the old A*, and the island test case more than 6
times, in a fraction of the memory.  This makes the continental
updates run 3.5 times faster, and the island updates 6% faster.
Distribution path assembly no longer dominates the continental
update's run time: it takes less than 10% instead of more than 70%.

In a sense, this is the path cache done right.

13 years agoExploit fast "multiple paths from same source" in distribution
Markus Armbruster [Mon, 21 Feb 2011 21:22:54 +0000 (22:22 +0100)]
Exploit fast "multiple paths from same source" in distribution

Dijkstra's algorithm can find multiple paths from the same source.
This is much faster than starting from scratch for every path.

Make distribution path assembly work that way.  This speeds up runs of
distributions to the same center.  The next commit will reorder path
searches to maximize the length of these runs.  It also has benchmark
results.

Allocates four bytes per sector, actually uses only the first 4*n
bytes, where n is the number of distributing sectors.

13 years agoNew path_find_visualize(), to aid debugging
Markus Armbruster [Mon, 21 Feb 2011 21:49:44 +0000 (22:49 +0100)]
New path_find_visualize(), to aid debugging

13 years agoAdd performance statistics to path finder
Markus Armbruster [Mon, 21 Feb 2011 21:30:41 +0000 (22:30 +0100)]
Add performance statistics to path finder

New function path_find_print_stats() prints a few numbers of interest
when compiled with PATH_FIND_STATS defined.

13 years agoOptimize Dijkstra's inner loop for hex maps
Markus Armbruster [Sat, 26 Feb 2011 16:40:13 +0000 (17:40 +0100)]
Optimize Dijkstra's inner loop for hex maps

Because the cost to enter a sector is independent of the direction of
entry, we visit sectors at most once.  Exploit that.

Beware: this is not the case for A*.  Pitfall for any future
generalization to A*.

Speeds up distribution path assembly by 35-40% in my tests.

13 years agoUse the new path finder for land paths, drop old A*
Markus Armbruster [Sat, 26 Feb 2011 15:06:09 +0000 (16:06 +0100)]
Use the new path finder for land paths, drop old A*

This gets rid of the memory leak mentioned in the previous commit.

To get rid of the buffer overruns for long paths mentioned in the
previous commit, make BestLandPath() fail when path length exceeds
1023 characters.

assemble_dist_paths() and move_ground() pass buffers with a different
size.  Eliminate assemble_dist_paths()'s buffer.  Update now works
regardless of distribution distance (the distribute command still
limits to 1023, to be fixed in a later commit).  Enlarge
move_ground()'s buffers.  Doubles the length of paths accepted by
explore, move, and transport.

I use two test cases to benchmark the path finders: "continental" (Hvy
Metal 2 updates) and "island" (Hvy Plastic 2 updates).

The new path finder runs my tests around 3-4 times faster than the old
A* without its caches.  That's enough to meet its cached performance
for "island", but it's only half as fast for "continental".  Not for
long; big speedups are coming.

13 years agoNew path finder
Markus Armbruster [Mon, 21 Feb 2011 19:38:09 +0000 (20:38 +0100)]
New path finder

We've been using Phil Lapsley's A* library to find land paths since
Chainsaw 3.  It's reasonably general, and uses relatively complex data
structures to conserve memory.  Unfortunately, it occasionally leaks a
bit of memory (see commit 86a187c0), and is unsafe for long paths (see
commit e30dc417).

To speed it up, v4.2.2 added two caches: the neighbor cache and the
path cache.

The neighbor cache attempts to speed up lookup of adjacent sectors.
It allocates 6 pointers per sector for that.  In my tests, this is
more, sometimes much more memory than the A* library uses.  See commit
7edcd3ea on branch old-astar for its (modest) performance impact.

The path cache attempts to speed up the update's computation of
distribution path costs.  There, A* runs many times.  Each run finds
many shortest paths, of which only the one asked for is returned.  The
path cache saves all of them, so that when one of them is needed
later, we can get it from the path cache instead of running A* again.
The cache is quite effective, but a bit of a memory hog (see commit
a02d3e9f on branch old-astar).

I'm pretty sure I could speed up the path cache even more by reducing
its excessive memory consumption --- why store paths when we're only
interested in cost?  But that's a bad idea, because the path cache
itself is a bad idea.

Finding many shortest paths from the same source has a well-known
efficient and simple solution: Dijkstra's algorithm[*].

A* is an extension of Dijkstra's algorithm.  It computes a *single*
path faster than Dijkstra's.  But it can't compute *many* shortest
paths from the same source as efficiently as Dijkstra's.

I could try to modify Phil's code to make it compute many shortest
paths from the same source efficiently: turn A* into its special case
Dijkstra's algorithm (at least for distribution path assembly), then
generalize it to the many paths problem.  Of course, I'd also have to
track down its memory allocation bugs, and make it safe for long
paths.

Instead, I'm replacing it.  This commit is the first step: a rather
unsophisticated implementation of Dijkstra's algorithm specialized to
hex maps.  It works with simple data structures: an array for the hex
map (16 bytes per sector), and a binary heap for the priority queue
(16 bytes per sector, most of it never touched).  This is more memory
than Phil's A* uses, but much less than Phil's A* with v4.2.2's
caches.

[*] To fully exploit Dijkstra's "many paths" capability, we need to
compute distribution paths in distribution center order.

13 years agoLicense upgrade to GPL version 3 or later
Markus Armbruster [Mon, 21 Feb 2011 18:37:40 +0000 (19:37 +0100)]
License upgrade to GPL version 3 or later

Why upgrade?  I'm not a lawyer, but here's my take on the differences
to version 2:

* Software patents: better protection against abuse of patents to
  prevent users from exercising the rights under the GPL.  I doubt
  we'll get hit with a patent suit, but it's a good move just on
  general principles.

* License compatibility: compatible with more free licenses, i.e. can
  "steal" more free software for use in Empire.  I don't expect to steal
  much, but it's nice to have the option.

* Definition of "source code": modernization of some details for today's
  networked world, to make it easier to distribute the software.  Not
  really relevant to us now, as we normally distribute full source code.

* Tivoization: this is about putting GPL-licensed software in hardware,
  then make the hardware refuse to run modified software.  "Neat" trick
  to effectively deny its users their rights under the GPL.  Abuse was
  "pioneered" by TiVo (popular digital video recorders).  GPLv3 forbids
  it.  Unlikely to become a problem for us.

* Internationalization: more careful wording, to harden the license
  outside the US.  The lawyers tell us it better be done that way.

* License violations: friendlier way to deal with license violations.
  This has come out of past experience enforcing the GPL.

* Additional permissions: Probably not relevant to us.

Also include myself in the list of principal authors.

13 years agoDocument buffer overrun for long land paths
Markus Armbruster [Sun, 20 Mar 2011 09:06:33 +0000 (10:06 +0100)]
Document buffer overrun for long land paths

BestLandPath(), BestDistPath() and best_path() are unsafe by design:
they take a path[] argument without a size, and blindly assume there's
enough space.  When that's wrong, bp_path() overruns the caller's
buffer.

move_ground() and assemble_dist_paths() provide space for 512
characters.  best(), dist(), path(), att_reacting_units(), s_commod()
and do_unit_move() provide space for 1024 characters.

A malicious player can arrange paths longer than that, but it takes a
lot of land.

BestAirPath() and BestShipPath() also take a path[] argument without a
size, but they're actually safe: bestownedpath() writes at most 100
(MAXROUTE) characters, perform_mission_bomb() provides space for 512,
sorde(), getpath(), do_unit_move() and nav_ship() for 1024.

13 years agoRemove pointless check for sea from finish_sects()
Markus Armbruster [Fri, 25 Feb 2011 18:45:46 +0000 (19:45 +0100)]
Remove pointless check for sea from finish_sects()

Checking "sea or unowned" is pointless, because sea is always unowned.

13 years agoOptimize assemble_dist_paths() for foreign distribution center
Markus Armbruster [Fri, 25 Feb 2011 18:40:08 +0000 (19:40 +0100)]
Optimize assemble_dist_paths() for foreign distribution center

You can't distribute to a foreign sector.  This case is relatively
rare.  However, unsuccessful path search is relatively expensive, and
the extra check doesn't really slow down the common case.

13 years agoOptimize dodistribute() for sectors with no distribution center
Markus Armbruster [Fri, 25 Feb 2011 07:08:05 +0000 (08:08 +0100)]
Optimize dodistribute() for sectors with no distribution center

import_cost is now -1 in that case, so checking that suffices.

13 years agoFix assemble_dist_paths()'s recovery from invalid dist center
Markus Armbruster [Fri, 25 Feb 2011 07:00:59 +0000 (08:00 +0100)]
Fix assemble_dist_paths()'s recovery from invalid dist center

The recovery avoided crashing here, but left the path costs undefined.
If they happend to be non-negative, dodistribute() still crashed.  Set
the costs to -1 to avoid that.

While there, oops on invalid distribution center.

13 years agoSpeed up export cost calculation in assemble_dist_paths()
Markus Armbruster [Sat, 19 Feb 2011 07:21:33 +0000 (08:21 +0100)]
Speed up export cost calculation in assemble_dist_paths()

Import and export paths enter the same sectors, except for the last
one.  Compute export cost from import cost instead of reverting the
import path.  Do it in dodistribute(), so that we need to store only
import costs.

13 years agoSupply charged mobility for backward path
Markus Armbruster [Fri, 18 Feb 2011 19:05:32 +0000 (20:05 +0100)]
Supply charged mobility for backward path

It used the path from supply recipient back to supply source.  Has
always been broken that way.

13 years agoDocument memory leak in as_search()
Markus Armbruster [Fri, 18 Feb 2011 18:10:28 +0000 (19:10 +0100)]
Document memory leak in as_search()

13 years agoMake bestpath work for deities in foreign land
Markus Armbruster [Fri, 18 Feb 2011 18:29:29 +0000 (19:29 +0100)]
Make bestpath work for deities in foreign land

Before, it only worked in land owned by the deity.

As always, paths can't cross international borders.

13 years agoMerge dodistribute() parameters dist_i_cost, dist_e_cost
Markus Armbruster [Fri, 18 Feb 2011 18:07:31 +0000 (19:07 +0100)]
Merge dodistribute() parameters dist_i_cost, dist_e_cost

Only one of them is used, depending on argument imex.  Replace them by
a single parameter path_cost.

13 years agoRemove dodistribute() parameter path
Markus Armbruster [Fri, 18 Feb 2011 18:01:25 +0000 (19:01 +0100)]
Remove dodistribute() parameter path

It was only used to see whether a path to the dist center exists.  Use
negative cost for that.

13 years agoSAVE_FINISH_PATHS hasn't been used since 4.2.2, remove it
Markus Armbruster [Fri, 18 Feb 2011 17:53:37 +0000 (18:53 +0100)]
SAVE_FINISH_PATHS hasn't been used since 4.2.2, remove it

Since 4.2.2, assemble_dist_paths() stores a dummy path instead of the
real path to the dist center.  That's possible because distribution
doesn't actually use the path, only whether it exists.

The code to store and free the real path is still around, under #ifdef
SAVE_FINISH_PATHS.  Remove it.

13 years agoPrint distribution costs when compiled with DISTRIBUTE_DEBUG
Markus Armbruster [Fri, 25 Feb 2011 05:13:23 +0000 (06:13 +0100)]
Print distribution costs when compiled with DISTRIBUTE_DEBUG

13 years agoCollect path-related stuff in path.h
Markus Armbruster [Sun, 11 Jul 2010 09:30:02 +0000 (11:30 +0200)]
Collect path-related stuff in path.h

13 years agoLog distribution path assembly's CPU use (user and system time)
Markus Armbruster [Wed, 16 Mar 2011 17:25:18 +0000 (18:25 +0100)]
Log distribution path assembly's CPU use (user and system time)

13 years agoLog update's CPU use (user and system time)
Markus Armbruster [Wed, 16 Mar 2011 17:24:58 +0000 (18:24 +0100)]
Log update's CPU use (user and system time)

13 years agoFleshed out getrusage() stub for Windows
Ron Koenderink [Sat, 19 Mar 2011 22:05:35 +0000 (16:05 -0600)]
Fleshed out getrusage() stub for Windows

13 years agoProvide a getrusage() stub for Windows
Markus Armbruster [Wed, 16 Mar 2011 06:16:21 +0000 (07:16 +0100)]
Provide a getrusage() stub for Windows

13 years agoMake savecore mind available disk space
Markus Armbruster [Sun, 13 Mar 2011 13:23:13 +0000 (14:23 +0100)]
Make savecore mind available disk space

13 years agoMake savecore check core file is accessible
Markus Armbruster [Sun, 13 Mar 2011 13:22:30 +0000 (14:22 +0100)]
Make savecore check core file is accessible

13 years agoFix bitmap overruns when WORLD_X * WORLD_Y not a multiple of 16
Markus Armbruster [Mon, 28 Feb 2011 05:58:51 +0000 (06:58 +0100)]
Fix bitmap overruns when WORLD_X * WORLD_Y not a multiple of 16

World-sized bitmaps were allocated with size WORLD_SZ() / 8, which
expands to (WORLD_X * WORLD_Y / 2) / 8.  The divisions truncate unless
WORLD_X * WORLD_Y is a multiple of 16.  The bitmaps were one byte too
small then.  Bitmap overruns happen when:

* A lookout looks at one of the last sectors of the sector file.
  Besides commands look and llook, this affects navigate and march
  sub-command 'l'.

* Command spy spies into one of the last sectors of the sector file.

* A map or nmap (but not a bmap) shows one of the last sectors of the
  sector file, or a sector that can see one of the last sectors
  (visual range is two sectors at 100% efficiency).  Besides commands
  lmap, map, nmap, pmap, smap, this affects move and transport
  sub-command 'm'.

Diagnosed with valgrind.

Already broken in BSD Empire 1.1 (bitmaps were on the stack then).

13 years agoFix pathrange()'s computation of the range's right limit
Markus Armbruster [Fri, 18 Feb 2011 18:36:55 +0000 (19:36 +0100)]
Fix pathrange()'s computation of the range's right limit

Because of the bug, the path command's maps weren't always fitted to
the path correctly.  Broken in commit 0f458d2c, v4.3.17

13 years agoLand units no longer hit allied mines
Markus Armbruster [Sun, 6 Feb 2011 15:28:12 +0000 (16:28 +0100)]
Land units no longer hit allied mines

13 years agoUse relations_with() in sendmessage()
Markus Armbruster [Sun, 6 Feb 2011 09:29:14 +0000 (10:29 +0100)]
Use relations_with() in sendmessage()

We know player != other.  Because we can have only one player in state
PS_PLAYING per country, and we know other->state == PS_PLAYING, it
follows that player->cnum != other->cnum.  Thus, no functional change.

Adds another call to getnatp() hidden in relations_with(), though.
Keeping that optimized isn't worth it.

13 years agoUse relations_with() for getrel(NP, THEM) where NP isn't THEM
Markus Armbruster [Sun, 6 Feb 2011 09:27:45 +0000 (10:27 +0100)]
Use relations_with() for getrel(NP, THEM) where NP isn't THEM

Replacing getrel(NP, THEM), where NP is known to be getnatp(US), by
relations_with(US, THEM) makes a difference only when US equals THEM.
Replace in places where it's obvious that they're not equal.

Adds a few calls to getnatp() hidden in relations_with().  Keeping
that optimized isn't worth it.

13 years agoUse relations_with() for US==THEM || getrel(NP, THEM)
Markus Armbruster [Sun, 6 Feb 2011 09:06:38 +0000 (10:06 +0100)]
Use relations_with() for US==THEM || getrel(NP, THEM)

Replace patterns like "US == THEM || getrel(NP, THEM)...", where NP is
known to be getnatp(US), by "relations_with(US, THEM)...".  No
functional change.

Adds a few calls to getnatp() hidden in relations_with(), though.
Keeping that optimized isn't worth it.

13 years agoUse relations_with() in unit_interdict()
Markus Armbruster [Tue, 1 Feb 2011 06:49:32 +0000 (07:49 +0100)]
Use relations_with() in unit_interdict()

No functional change, because the value of rel only matters when cn !=
victim, and then it's the same as before.

The new value of rel permits simplifying cn != victim && rel <=
NEUTRAL to just rel <= NEUTRAL

13 years agoUse relations_with() in owned_and_navigable()
Markus Armbruster [Sun, 30 Jan 2011 17:32:19 +0000 (18:32 +0100)]
Use relations_with() in owned_and_navigable()

This removes a special case for POGO (#0).  Before, unoccupied sectors
were treated as "own or allied" for POGO, but not for other deities.

Impact on callers:

* BestAirPath() is not affected, because the change is only reachable
  with a non-null bigmap argument.

* sorde() and nav_ship() pass a non-zero ship owner.  sorde() ensures
  that itself, and prod_ship() does it for nav_ship().

* unit_path() passes the player number when called with a ship
  argument, i.e. in the navigate command.  Player number is zero for
  POGO.  Since deities can't navigate foreign ships, this can happen
  only when POGO navigates dead ships.  Yes, that's possible, needs
  fixing.

* getpath() passes the player number (zero for POGO) when called with
  argument P_SAILING, i.e. by the sail command.

Thus, the change makes navigate's and sail's path finding work for
POGO exactly like it does for other deities.  That's fine.

13 years agoUse relations_with() in getilists()
Markus Armbruster [Sun, 30 Jan 2011 16:37:36 +0000 (17:37 +0100)]
Use relations_with() in getilists()

No functional change, even though this changes rel[intruder] from
NEUTRAL to ALLIED.  Uses of rel[]:

* getilists() and ac_encounter() compare rel[cn] to HOSTILE.  No
  change, because NEUTRAL and ALLIED are both greater than HOSTILE.

* ac_encounter() compares rel[cn] to ALLIED, but only when cn !=
  plane_owner.  Because it passes plane_owner as argument for
  getilists() parameter intruder, rel[cn] can't refer to the changed
  element of rel[] here.

The new value of rel[plane_owner] permits simplifying cn ==
plane_owner || rel[cn] == ALLIED to just rel[cn] == ALLIED.

13 years agoUse relations_with() in nav_loadship()
Markus Armbruster [Sun, 30 Jan 2011 16:10:43 +0000 (17:10 +0100)]
Use relations_with() in nav_loadship()

No functional change, because the value of rel only matters when
sectp->sct_own != sp->shp_own, and then it's the same as before.

The new value of rel permits simplifying sectp->sct_own == sp->shp_own
|| rel >= FRIENDLY to just rel >= FRIENDLY.

13 years agoUse relations_with() in shp_fort_interdiction()
Markus Armbruster [Sun, 30 Jan 2011 15:39:38 +0000 (16:39 +0100)]
Use relations_with() in shp_fort_interdiction()

No functional change, because the change affects only
notified[victim], which isn't used in the loop around
notify_coastguard(), and gets overwritten before the interdiction fire
loop.

13 years agoUse relations_with() in lnd_mar_one_sector()
Markus Armbruster [Sun, 30 Jan 2011 15:31:02 +0000 (16:31 +0100)]
Use relations_with() in lnd_mar_one_sector()

No functional change, because the value of rel only matters when
sect.sct_own != actor, and then it's the same as before.

The new value of rel permits simplifying sect.sct_own != actor && rel
!= ALLIED to just rel != ALLIED.

13 years agoUse relations_with() in player_relstr()
Markus Armbruster [Sun, 30 Jan 2011 15:26:22 +0000 (16:26 +0100)]
Use relations_with() in player_relstr()

No functional change, because argument is never player->cnum.

13 years agoUse relations_with() for getrel(getnatp(US), THEM) where US!=THEM
Markus Armbruster [Sat, 29 Jan 2011 13:34:40 +0000 (14:34 +0100)]
Use relations_with() for getrel(getnatp(US), THEM) where US!=THEM

Replacing getrel(getnatp(US), THEM) by relations_with(US, THEM) makes
a difference only when US equals THEM.  Replace in places where it's
obvious that they're not equal.

Note: getsect() sets player->owner to "player is god or owns this
sector".  Thus, after getsect(..., &sect), sect.sct_own ==
player->cnum implies player->owner.  Conversely, !player->owner
implies sect.sct_own != player->cnum.  Similarly for getship(),
getplane() and nxtitem().