Pass the more obviously correct plane_owner instead of player->cnum.
They're the same, actually.
When deities could still fly foreign planes (before commit 2023b47c),
they weren't. ac_encounter() updated the plane owner's in-memory
bmap, but wrote the current player's bmap to disk.
satdisp_sect() updated the in-memory bmap, but failed to write the
updates to disk. Its callers already update bmap from other sources,
so move this update there, and connect it to the existing write back.
The only user is reco(), so the restriction is fine. Several
functions called on behalf of mission_flags assumed it already:
plane_sweep(), sathead(), satdisp_sect(), satdisp_units(). Simplify
the rest accordingly: plane_sona() and ac_encounter() itself.
Much of the code assumes that only the land unit's owner can march it.
The assumption is correct, because lnd_mar() leaves foreign land units
behind with a bogus "was disbanded at" message (suppressed for country
It would be nice to let deities march foreign land units, but the
assumption is not trivial to remove. For now, just avoid the bogus
message.
Historical note: it looks like deities used to be able to march
foreign land units just fine until Empire 2 factored common code out
of navigate, sail and autonav, and updated march to match navigate.
Likewise, it looks like they could board with foreign land units until
Empire 2 factored out common ground combat code. Commands attack and
assault have always rejected foreign land units, even for deities.
Much of the code assumes that only the ship's owner can navigate it.
The assumption is correct, because shp_nav() leaves foreign ships
behind with a bogus "was sunk at" message (suppressed for country #0).
It would be nice to let deities navigate foreign ships, but the
assumption is not trivial to remove. For now, just avoid the bogus
message.
Historical note: it looks like deities used to be able to navigate
foreign ships just fine until Empire 2 factored common code out of
navigate, sail and autonav.
Much code assumes that only the plane's owner can fly it.
pln_airbase_ok() oopses since commit 446f1991. Before, flying planes
from carriers failed with a bogus "not valid for" message, and flying
from sectors had output misdirected to the plane's owner.
It would be nice to let deities fly foreign planes, but the assumption
is not trivial to remove, so just satisfy it for now.
Historical note: it looks like deities used to be able to fly foreign
planes just fine until Chainsaw 3 added missions. The launch command
has always rejected foreign planes, even for deities.
Such misuse creates a bulletin with a partial line. The read command
normally merges it with the next one, but if the bulletins are more
than five seconds apart (clock jumped somehow), we get a bulletin
header in the middle of a line.
Don't use multiple calls of mpr() to print a single line, because that
creates a separate bulletin for each part. The read command normally
merges the bulletins, but if the bulletins are more than five seconds
apart (clock jumped somehow), we get a bulletin header in the middle
of a line.
While there, wrap long "blam" lines. Can only happen for bomb loads
above 16. Stock game needs a tech 406 jhb for that.
The mpr() misuse was introduced in Empire 2.
Don't use multiple calls of mpr() to print a single line, because that
creates a separate bulletin for each part. The read command normally
merges the bulletins, but if the bulletins are more than five seconds
apart (clock jumped somehow), we get a bulletin header in the middle
of a line.
The mpr() misuse was introduced in Empire 2.
Don't use multiple calls of mpr() to print a single line, because that
creates a separate bulletin for each part. The read command normally
merges the bulletins, but if the bulletins are more than five seconds
apart (clock jumped somehow), we get a bulletin header in the middle
of a line.
The mpr() misuse was introduced in Empire 2.
Not nice, because it could beep many times, and could put beeps in
bulletins. Moreover, it misused mpr() and thus put the beep in its
own bulletin. The read command normally merges this bulletin with the
adjacent ones, but if the bulletins are more than five seconds apart
(clock jumped somehow), we can get an empty bulletin just for the
beep.
Beeping was added in v4.0.18.
Output went to the owner of the nuke instead of the player.
Fortunately, they're the same in normal usage. They can differ only
when a deity drops a foreign nuke from a foreign plane.
The fix also cleans up a misuse of mpr() in kaboom(): it used multiple
calls to print a single line, which creates a separate bulletin for
each part. The read command normally merges the bulletins, but if the
bulletins are more than five seconds apart (clock jumped somehow), we
get a bulletin header in the middle of a line. Fortunately, that
could happen only when a deity drops a foreign nuke. Before commit
a269cdd7 (v4.3.23), it could also happen for missions.
Broken in Empire 2.
It showed unit coordinates in unit's coordinate system instead of the
player's. Fortunately, they're the same, since even deities can't
navigate foreign ships or march foreign land units.
msl_launch() printed some lines to the player instead of the missile
owner when the missile exploded on launch. They are different when
the launch is for a mission or an interception. This disclosed the
the owner's origin. Broken in Empire 2.
When refusing to march foreign land units, it reported the land unit's
location in the land unit's coordinate system instead of the player's.
Fortunately, they're the same, since even deities can't march foreign
land unit.
When the nuke bounced off a sanctuary, the bulletin to the sanctuary
owner used the attacker's coordinate system. This disclosed the
attacker's origin.
When reporting sweeps, it reported the location in the plane owner's
coordinate system instead of the player's. Fortunately, they're the
same in normal usage. They can differ only when a deity flies foreign
planes.
These ships could only use their x-light slots for x-light planes, not
their plane slots. For instance, agc (30 x-light slots, 32 plane
slots) could load only 30 sams, and mb (0 x-light slots, 10 plane
slots) could not load any sams.
Culprit is could_be_on_ship(). Broken in commit 3e370da5, v4.3.17.
When an inefficient missile exploded on launch, it could damage
itself. The damage had no effect, because the missile gets used up
right after. But it triggers a seqno mismatch oops, in laun(). Fix
by making msl_launch() set PLN_LAUNCHED before the explosion.
This case was missed in commit 7bc63871, v4.3.14. It didn't oops
until sequence numbers were added in v4.3.15.
When d of n cargo items are discarded for want of space, pln_dropoff()
reported -d items discarded and -d items unloaded. Already broken in
BSD Empire 1.1.
Before commit a269cdd7, pln_damage() returned zero when the damage was
nuclear, and callers used that to bypass conventional damage code.
Zero value can't happen anymore.
Ships can expend shells to defend against missiles, in
shp_missile_defense(). Any shell use by the target ship got wiped out
when shp_missile_interdiction() wrote back the target ship, triggering
a seqno mismatch oops.
Ships get updated when they launch planes to intercept interdicting
planes, in mission_pln_equip(). Any petrol use by the target ship got
wiped out when shp_mission_interdiction() wrote back the target ship,
triggering a seqno mismatch oops.
Fix by re-reading the target ship in shp_damage_one(). This also
affects shp_fort_interdiction(), where it is not necessary. A bit
inefficient, but let's keep this fix simple.
Commit a269cdd7 (v4.3.23) removed the nuclear damage. But it left the
nuke on the missile, which made pln_damage() oops and return zero
damage.
Fix by destroying the nuke separately.
Movement stops when shp_interdict() or lnd_interdict() report
interdiction. However, they reported it only when there was
interdiction damage.
Zero interdiction damage commonly happens when interdicting missiles
miss, or all bombers abort. Stopping regardless of damage makes more
sense there.
Moreover, not stopping is buggy: do_unit_move() needs to take care not
to wipe out updates made by interdiction to the moving ships or land
units. It does so only when it stops. Updates made by interdiction
without interdiction damage could get wiped out, triggering a seqno
mismatch oops.
Known ways moving ships and land units can get updated by interdiction
despite there is no interdiction damage:
* Interdicting bombers get intercepted by planes based on a navigating
carrier, carrier gets charged petrol. The bug wipes out the petrol
use.
* Marching land units get interdicted by planes, but all planes miss.
Sufficiently large collateral damage to the sector can still damage
the land units. The bug wipes out the damage to land units.
To make shp_interdict() and lnd_interdict() report interdiction
regardless of damage, change lnd_missile_interdiction(),
lnd_fort_interdiction(), lnd_mission_interdiction(),
shp_missile_interdiction(), shp_fort_interdiction(),
shp_mission_interdiction() to return whether there was interdiction.
Before, they returned whether there was damage.
Change unit_interdict(), perform_mission(), perform_mission_land(),
perform_mission_ship(), perform_mission_msl(), and
perform_mission_bomb() to return -1 for no interdiction, so that
callers can distinguish no interdiction from interdiction with no
damage.