put_empobj() used struct empobj member uid, which is valid only for
units. Existing users pass only units, fortunately. Fix by making it
take type and uid parameters.
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.
Read-only was a bit of a misnomer: you could write to the table by
obtaining a pointer into it from ef_ptr(), you just couldn't write to
the backing file.
Semantic changes:
* ef_flush() is now allowed when the table is file-backed or privately
mapped. Before, it had to be file-backed. Flushing a privately
mapped table does nothing, just like flushing a read-only table did.
* ef_write() is now allowed when the table is file-backed or fully
cached. Before, it had to be file-backed and not read-only.
Writing to a privately mapped file-backed table doesn't write to the
file.
* ef_extend() is not implemented for privately mapped tables, just
like it wasn't implemented for read-only tables.
A bridge (span or tower) must be splashed when it gets damaged below
SCT_MINEFF. Likewise when its last supporting sector (bridge head or
tower) gets damaged below SCT_MINEFF, unless EASY_BRIDGES is enabled.
We need to check this whenever a bridge head, span or tower gets
damaged. This is done in three places, and all of them screw up:
* checksect() ignores damage to bridge heads. It also leaves writing
back the sector it checks to the caller, which never happens when
it's called from sct_postread().
Note that checksect() drowns all planes on bridges it splashes.
Functions that need to exempt flying planes from such a fate have to
splash bridges themselves.
* sect_damage() ignores damage to bridge towers, and damage to bridge
spans unless EASY_BRIDGES is enabled. It then runs checksect(),
which compensates for these omissions, but happily drowns the planes
sect_damage() attempts to protect.
* eff_bomb() ignores damage to bridge heads. Collateral damage makes
sect_damage() run, which compensates for the omission.
This causes the following bugs:
* Efficiency damage going through sect_damage() can drown planes it
shouldn't. This affects pinpoint bombing when collateral damage
splashes a bridge, and strategic bombing. The drowned planes then
crash and burn when they attempt to land at their (just splashed)
base.
* Efficiency damage to bridge heads not going through sect_damage()
fails to collapse unsupported bridges. This affects pin-bombing
efficiency without collateral damage, and ground combat. Also deity
commands edit, setsector and add, but that could be regarded as a
feature.
* If the sector file somehow ends up with an inefficient bridge span,
it collapses on every read again and again, until it collapses on a
write. Related problems exist with other actions of checksect(),
and they're not addressed here.
* If the sector file somehow ends up with adjacent inefficient bridge
towers, checksect() on any of them recurses infinitely:
- checksect() inefficient tower T1
- knockdown() T1, but don't write that back to the sector file
- bridgefall() T1; this reads all adjacent sectors, including
inefficient towert T2
- checksect() T2
- knockdown() T2, but don't write that back to the sector file
- bridgefall() T1; this reads adjacent sectors including T1
- checksect() T1
...
This commit creates a new function bridge_damaged() to splash any
bridges that became inefficient or unsupported after damage to a
sector. To avoid the inifinite recursion, we call it in
sct_prewrite() instead of checksect().
No uses knockdown() outside bridgefall.c remain, so give it internal
linkage.
Split ef_init() into two functions: empfile_init() for initialization,
and empfile_fixup() to fix it up for configuration. Put them next to
empfile[]. Move the call to empfile_init() from behind emp_config()
to before it.
Mil are not required for building units since 4.0.0. l_mil was still
initialized to l_item[I_MILIT], and used instead of that in a couple
of places. Fix those, and remove the initialization.
read_builtin_tables() wanted to run in builtindir, and
read_custom_tables() wanted to run in configdir. Bothersome. Use new
fopenat() to relax those requirements.
The chdir() satisfying them are now superflous, remove them.
File names in econfig need to be interpreted relative to configdir.
This wasn't the case everywhere for keys data and info.
Fix this by changing variables gamedir and infodir to hold absolute
names. Change builtindir likewise, for consistency. Store the values
from econfig in gamedir_conf, infodir_conf and builtindir_conf.
Uses new fnameat() to derive absolute names from possibly relative
ones.
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.
The function that gave its name to this file is long gone, the file's
description is bogus, and it contains just one definition. Move that
to ../subs/border.c, and delete the file.
There are several files with land unit subroutines. This one is in an
awkward place: it depends on stuff from ../subs, which contributes to
libcommon.a's ugly dependencies. Move its contents to logical places
(use internal linkage where possible), and remove it.
implemented correctly by asynchronous clients --- unless a client
waits for a prompt after sending the execute command and its argument,
it is prone to send more input before the C_EXECUTE arrives. That
input overtakes the contents of the script file. This is almost
certain to happen when the execute is in a script file. Disabling
that is probably more useful and certainly less painful than
documenting this mess. The client rejects nested execute since
servcmd.c rev. 1.42.
(EXEC): new.
(player_coms): Require it for execute.
(player_set_nstat): Set it in nstat.
(execute): Clear it in nstat.
player->ncomstat for command permissions. Side effect: status() no
longer notifies deities when they go broke or become solvent.
(dispatch): Don't distinguish between transiently and permanently
unavailable commands. Didn't really work anyway.
(player): Remove unused member ncomstat.
(init_nats): Use it. No functional change.
(status): Use it. This sets player->nstat from scratch, not just
MONEY and CAP.
(brea): Don't bother to update player->nstat, status() will.
(carriersatxy, pln_onewaymission): Pass zero. No functional change.
(pln_airbase_ok): Pass whether the plane is a missile. This fixes
non-x-light missiles on ships without capability M_FLY. Broken in
rev. 1.76. Launch and interdict weren't affected. Air defense was,
but the stock game has only x-light SAMs.
(player): New member eof.
(recvclient): Return -1 without receiving input when it is set. Set
it on receipt of "ctld\n".
(execute): Clear it after receiving the script.
Check player->cnum only when noisy. Update existing caller to pass 1.
No functional change.
(mission_pln_airbase_ok): Remove, use pln_airbase_ok() instead. No
functional change.
more so: additionally, any of P_E, P_K, P_L satisfied any subset of
P_E, P_K, P_L. Chainsaw fixed this one in plnsub.c, but not here.
Remove, use the fixed pln_wanted() instead.
(pln_wanted): External linkage.
(fit_plane_on_ship, fit_plane_on_land): New.
(pln_oneway_to_carrier_ok, put_plane_on_ship, count_planes)
(put_plane_on_land, count_land_planes): Use them. No functional
change.
(fit_plane_off_ship, fit_plane_off_land): New.
(take_plane_off_ship, take_plane_off_land): Use them. This oopses
when the carriers plane counter underflows.
(take_plane_off_ship): Document that carrier's plane counters may be
screwed up.
(take_plane_off_ship, take_plane_off_land): Oops when the plane isn't
on the carrier.
(take_plane_off_ship, take_plane_off_land): Don't fail when the plane
to be taken off can't go on this type of carrier, just take it off.
No error condition left, so return void. Callers couldn't do anything
useful with the status anyway, and most didn't bother. Change those
that did.
a seed for the random function.
(nightlybuild.sh): Add the -R 1 for the server.
(nightlybuild.sh): Switch to -R 1 for the fairland as 1 is safer.
Some systems might generate lousy randomness from a
zero seed.
(prng.patch): Not required anymore, -R 1 is used instead.
(main, emp_server.6): Rename -r and -R to -u and -U. "-R" is now used for random seed.
[_WIN32] (mkdir): Use it. Last argument is no longer ignored, which
was a bug. Move declaration to unistd.h, which isn't quite right, but
works for us.