Sub-command 'm' calls display_region_map() to display a map. The map
is centered on the current sector by default. It extended one sector
farther to the right and down than to the left and up. Odd, and
inconsistent with the map size used by unit_map() for navigate and
march sub-command 'M'. Fix that.
Change struct range from exclusive to inclusive upper bounds, for
consistency with struct realmstr and the area syntax. Also fix many
bugs.
real()'s conversion from struct range's exclusive upper bounds to
struct realmstr's inclusive upper bounds could underflow and store -1
in the realms file. Harmless, because its users didn't mind:
list_realm() and nstr_exec_val() convert back to relative coordinates,
and sarg_getrange() is only used by sarg_area(), which happened to
undo the damage. The change to inclusive upper bounds gets rid of the
broken conversion.
xyinrange() incorrectly treated the upper bound as inclusive, unless
the bounds were equal. Impact:
* nxtitem() and nxtitemp() cases NS_AREA and NS_DIST attempted to hack
around xyinrange()'s lossage(!), but screwed up: sectors on the
lower bound of of a range spanning the the whole world were skipped.
This affected all command arguments that support area or distance
syntax for items. In sufficiently small worlds, it could also make
radar miss satellites and ships, sonar miss ships, satellite miss
ships and land units, nuclear detonations miss ships, planes, land
units and nukes, automatic supply miss ship and land unit supply
sources, ships and land units fail to return fire, ships fail to
fire support.
* draw_map() could draw units sitting just right or just below of the
mapped area. No effect, as these parts of the map weren't actually
shown.
xydist_range() produced an inclusive upper bound when it decided that
the range covers everything in that dimension (which it didn't get
quite right either). This could make snxtsct_dist() and
snxtitem_dist() initialize the iterator with an incorrect upper bound.
Similar impact as the xyinrange() / nxtitem() lossage.
border() could print the hundreds line unnecessarily.
snxtsct() and snxtsct_all() screwed up for odd WORLD_Y: they failed to
include (WORLD_Y - 1) / 2 in the y-range. This affected all command
arguments that support "*" syntax for sectors, plus add ... c, power
n, and break.
snxtsct_all() failed to normalize the bounds (presumed harmless).
There were a few correct, but somewhat unclean uses of struct range
with inclusive upper bounds:
* nat_reset() used one internally.
* pathrange() worked with inclusive upper bounds internally, but
corrected to exclusive upper bounds before passing the range out.
* sarg_getrange() worked with inclusive upper bounds. Its only caller
sarg_area() corrected that to exclusive upper bounds.
The change to inclusive upper bounds cleans this up.
unit_map() and xysize_range() had no issues (isn't that amazing?), but
need to be updated for the changed struct range semantics.
The correct method to compute indexes into a map buffer for a struct
range is deltx(), delty().
path() used deltax(), deltay() instead, which yield correct results
only for indexes up to half the world size. Pathes spanning larger
areas were screwed up.
sona(), radmap2(), satmap() also used deltax(), deltay(), but only
with arguments where those yield correct results.
draw_map() used xnorm(), ynorm() instead, which is correct, but less
clear and less efficient.
Old code didn't check value of sctoff() for success. But it can't
fail, because we already took care of the condition that can make it
fail. Moreover, the arguments are already normalized. Therefore, we
can just call XYOFFSET().
The get_FOOp() macros are generally avoided outside the update,
because direct access to the sector cache needs synchronization to be
safe. unit_map() didn't access the cache directly until it was
converted from get_ship() & friends to get_empobjp() in commit
fec9878c. Switching to get_empobj() reverts the change to direct
access while keeping the simplification.
get_empobj_chr() and emp_obj_chr_name() access struct sctstr member
sct_type through struct empobj member type. This is technically
non-portable, because the two differ in signedness. It was also
undocumented. Fix by making sct_type signed. sct_newtype as well,
for consistency.
map_char() uses unsigned char for a sector type argument. Change that
to int. Matches how this is done elsewhere.
Move stuff to untangle the ugly cyclic dependencies between the
archives built for selected subdirectories of src/lib/:
* Move common/io.c to empthread/ because it requires empthread stuff
* Move parts of subs/nstr.c to common/nstreval.c to satisfy
common/ef_verify.o
* Move getstarg.c getstring.c onearg.c from gen/ to subs/ because they
require stuff from there
* Move bridgefall.c check.c damage.c empobj.c journal.c maps.c
sectdamage.c from common/ to subs/ because they require stuff from
there
* Move cnumb.c from subs/ to common/ to satisfy common/type.o
* Move log.c fsize.c from common/ to gen/ because they really belong
there
* Move emp_config.c mapdist.c from gen/ to common/ because they really
belong there, and require stuff from libglobal.a
Also package as/ as libas.a to satisfy common/path.o.
Remaining dependencies:
lib needs
--------------------------------------------
libas.a libglobal.a
libcommon.a libas.a libglobal.a libgen.a
libgen.a
libglobal.a
liblwp.a libgen.a
libw32.a[*] libgen.a
[*] Except for service.o, which can only be linked into the server
Link order now: liblwp.a libcommon.a libas.a libgen.a libglobal.a
libw32.a. The position of libw32.a is not quite right, but works
anyway.