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.
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.
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.
(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.
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.
xdump:
(gamestr): New member game_upd_disable.
(game_ca): Update accordingly.
(game_ctrl_update): New.
(disa, enab): Use it.
(updates_disabled): Rewrite and move to game.c
(disablefil): Remove.
(show): New sub-command.
(player_coms): Update its c_form.
(show_updates, fmttime2822): New.
(vers): Show game_days and game_hours.
(upda): Mark obsolete and point to show updates.
(vers): Point to show rather than update.
Rewrite much of info zdone.
(lndstr, plnstr, sctstr, shpstr): Change timestamp members lnd_access,
pln_access, sct_access, shp_access from real time (time_t) to ETUs
within a turn (short).
(land_ca, plane_ca, sect_ca, ship_ca): Update accordingly.
(build_ship, build_land, build_bridge, build_plane, build_tower)
(explore, check_trade, bsanct, takeover, takeover_ship)
(takeover_land): Use game_tick_to_now() instead of time() to update
the timestamp. Change check_trade(), takeover_ship(), takeover_land()
to do that only when MOB_ACCESS is enabled, for consistency.
(lupgr, supgr, pupgr, takeover_ship): Don't touch the timestamp where
mobility isn't touched either.
(sct_do_upd_mob, shp_do_upd_mob, lnd_do_upd_mob, pln_do_upd_mob): Use
game_tick_to_now() instead of increase_mob() to compute ETUs since
the timestamp and update the timestamp. Closes#1012699.
(increase_mob): Remove.
(mob_sect, mob_ship, mob_land, mob_plane): sct_do_upd_mob() & friends
no longer do the right thing at the update. Use game_reset_tick() and
pass its result directly to do_mob_sect() & friends. This is only
correct when argument is etu_per_update, which it always is. Remove
parameter. Callers changed.
(do_mob_sect, do_mob_ship, do_mob_land, do_mob_plane): Oops on
negative argument.
(mob_acc_globals, timestampfil, mobupdate, updating_mob)
(update_all_mob, timestamp_fixing, update_timestamps, mobility_check):
The mobupdate command was important to let deities manually
synchronize mobility updating with updates. That's no longer needed.
The code behind it is somewhat hairy and ugly, and updating it to work
with the Empire clock is just not worth it. Remove. Users changed.
(player_coms): Update accordingly.
(upda): Remove display of mobility updating state.
(mobility_init): No need to fix up mobility on startup, as the Empire
clock runs normally even when the server is down. Remove. Caller
changed.
(schedulefil): New.
(set_dirs, set_paths): Rename. Initialize schedulfil.
(read_schedule): New. Can read several updates, which will be used in
later changesets.
(update_time): Change to array. Will be used in later changesets.
(update_schedule_anchor): New.
(update_init): Initialize it.
(update_get_schedule): New.
(update_init): Call it to initialize update_time[].
(update_sched): Rewrite.
(update_forced, update_wanted): Replace.
(update_reschedule): New.
(main): Call it on SIGHUP to reload the schedule.
(update_trigger, update_force, force, player_coms): Drop force's
capability to schedule updates in the future, because it's not worth
the trouble to implement again. Deities can simply edit the schedule
file to schedule updates. Remove update_force() and
update_trigger()'s parameter.
(upda): Update for new scheduler. Take care to keep output the same
as far as possible, even though it's ugly, to avoid breaking clients.
(update_policy, adj_update, update_times, hourslop, blitz_time):
econfig keys removed.
(update_demand, UPD_DEMAND_NONE, UPD_DEMAND_SCHED, UPD_DEMAND_ASYNC)
(update_demandpolicy, UDP_NORMAL, UDP_TIMES, UDP_NORMAL, UDP_BLITZ)
(UDP_MAX, UDP_DEFAULT, UDDEM_TMCHECK, UDDEM_COMSET, UDDEM_DISABLE)
(UDDEM_MAX, UDDEM_DEFAULT): econfig key and values replaced. Users
changed. wantupd.h is now empty, remove.
(demand_check): External linkage.
(update_policy_check): Now pointless, remove.
(is_daytime_near, min_to_next_daytime, regular_update_time)
(scheduled_update_time, next_scheduled_time, updatetime)
(next_update_time, next_update_check_time): Unused, Remove.
(demand_check, demandupdatecheck): Move call of demand_update_time()
from demand_check(), which controls all demand updates, to
demandupdatecheck(), which controls only unscheduled ones. Fixes
update command not to lie about the next scheduled demand update.
(demandupdatecheck): Check updates_disabled() so that zdone no longer
claims to trigger an update when it can't.
land_unit as well.
(do_unit_move): Add view option for land units using unit_view().
Combine ship and land viewing using the unit_view().
(shp_view): Remove, not used any more, replaced by unit_view().
type. Make it abstract because that's possible. Change data layout
so that the slots belonging to a sector are together in memory, it's
nicer to the cache.
(bp): The new type. Users changed.
(get_wp): Update accordingly.
(alloc_bp): New.
(update_main, calc_all): Use it. Before, calc_all() allocated 1/7
more than necessary.
(opt_AUTO_POWER, update_power): New.
(update_main): Implement AUTO_POWER.
(powe): Disable power new when AUTO_POWER is on.
(powe): New power update.
(gen_power): Compute power into buffer passed by caller, make write to
power file optional.
(map): Call new function do_map().
(display_region_map): Modify to use do_map() instead of map().
(tran_nmap, tran_pmap, cmd_move_map): Modify to accomodate
the modified display_region_map() function.
other. Ensure headers in include/ can be included in any order
(except for econfig-spec.h, which is special). New header types.h to
help avoid inclusion cycles. Sort include directives. Remove some
superflous includes.
and tran_pmap() so that unit number arguments are interpreted
sensibly. Users changed.
(display_region_map): New.
(cmd_move_map, tran_nmap, tran_pmap): Use it.
type parameter as it can be determined from the empobj parameter.
(oprange): Remove getting the unit information again as it is contained
in the empobj parameter passed in.
oprange, show_mission, nameofitem, build_mission_list_type,
unit_map, xdvisible, trdswitchown, ontradingblock, trad, check_trade,
unit_type_name, start_stop_unit, scut, scra, mission, multifire,
perform_mission, fuel, NSC_GENITEM): Replace struct genitem with
struct empobj. Remove genitem.h and create a new file empobj.h.
Replace multiple instances of unions of ef_type structures with
one standard union empobj_storage which is a superset of the individual
instances.