13 years agoUpdate change log again for 4.3.24 v4.3.24
Markus Armbruster [Tue, 26 Jan 2010 21:30:24 +0000 (22:30 +0100)]
Update change log again for 4.3.24

13 years agoFix generation numbers for order command
Markus Armbruster [Tue, 26 Jan 2010 21:20:16 +0000 (22:20 +0100)]
Fix generation numbers for order command

orde() uses a "clever" trick to get away with just one
check_ship_ok(): it makes a copy of the ship in the beginning, and
checks it at the end.  Generation numbers (commit 2fa5f652) break this
trick.  It could be fixed by manually marking the ship fresh.
Instead, check the ship the stupid, straightforward way, without a

13 years agoNormalize order's reaction to bad input
Markus Armbruster [Tue, 26 Jan 2010 21:02:34 +0000 (22:02 +0100)]
Normalize order's reaction to bad input

Consistently fail the command on bad or missing argument.  Before, it
merely skipped to the next ship in some cases.

13 years agoGet third argument of "order l" the ordinary way
Markus Armbruster [Tue, 26 Jan 2010 20:48:26 +0000 (21:48 +0100)]
Get third argument of "order l" the ordinary way

Now prompts when the argument is empty.  Before, that was interpreted
as zero.  Not likely to affect players.

13 years agoClean up dead code in orde()
Markus Armbruster [Tue, 26 Jan 2010 20:23:10 +0000 (21:23 +0100)]
Clean up dead code in orde()

Does not change optimized code (gcc -O) apart from __LINE__.

13 years agoFix windows client not always exiting
Ron Koenderink [Mon, 25 Jan 2010 02:45:51 +0000 (20:45 -0600)]
Fix windows client not always exiting

The call to WSAEnumNetworkEvents() was reseting network
events in particular WSAECONNRESET was sometimes being lost
causing the client to not exit.  The WSAEnumNetworkEvents()
was called from fd_is_socket() and has been replace with
getsockopt() to determine if the fd is socket or not.

Broken in commit 4d40a275, v4.3.23

13 years agoUpdate change log for 4.3.24
Markus Armbruster [Mon, 18 Jan 2010 18:35:37 +0000 (19:35 +0100)]
Update change log for 4.3.24

13 years agoClean up dead stores
Markus Armbruster [Sat, 16 Jan 2010 16:40:28 +0000 (17:40 +0100)]
Clean up dead stores

Does not change optimized code (gcc -O).

Spotted by the Clang Static Analyzer.

13 years agoFix navigate/march crash on funny path arguments
Markus Armbruster [Sat, 16 Jan 2010 16:15:22 +0000 (17:15 +0100)]
Fix navigate/march crash on funny path arguments

For an argument consisting of a valid path plus whitespace,
do_unit_move() eventually passed the whitespace suffix to parse(),
then dereferenced player->argp[0].  But that was null.

Broken in commit 0c12d837, v4.3.7.  Trivial for players to trigger.

13 years agoFix player_login() not to print null pointer
Markus Armbruster [Sat, 16 Jan 2010 15:29:41 +0000 (16:29 +0100)]
Fix player_login() not to print null pointer

When the input line contains only whitespace, player->argp[0] is null
after parse().  This condition was not checked, comtch() returned
M_IGNORE, and code handling that printed the null pointer.  Some
systems (GNU, Windows) deal gracefully with printing null strings,
others crash.  Trivial to trigger remotely.

Before the fix, the value of parse() was assigned, but never used, and
that was spotted by the Clang Static Analyzer.

13 years agoClean up useless getnatp() in conv(), nav_map(), tele()
Markus Armbruster [Sat, 16 Jan 2010 09:14:43 +0000 (10:14 +0100)]
Clean up useless getnatp() in conv(), nav_map(), tele()

Spotted by the Clang Static Analyzer.

13 years agoMove -h to the end of the emp_server -h output
Markus Armbruster [Sat, 16 Jan 2010 08:31:08 +0000 (09:31 +0100)]
Move -h to the end of the emp_server -h output

This is consistent with the other programs.

13 years agoMake empire, empsched and files catch extra operands
Markus Armbruster [Sat, 16 Jan 2010 08:29:53 +0000 (09:29 +0100)]
Make empire, empsched and files catch extra operands

This also avoids a dead increment ap++ in src/client/main.c reported
by the Clang Static Analyzer.

13 years agoMake empire and files not print usage on bad option
Markus Armbruster [Sat, 16 Jan 2010 08:22:48 +0000 (09:22 +0100)]
Make empire and files not print usage on bad option

Point to -h instead.  This is consistent with the other programs.

13 years agoFix lwpReschedule()'s assertion "have runnable thread"
Markus Armbruster [Fri, 15 Jan 2010 21:06:51 +0000 (22:06 +0100)]
Fix lwpReschedule()'s assertion "have runnable thread"

If there is no runnable thread, we're deadlocked.  lwpReschedule() has
an assertion to catch this.  But it didn't work, and the code
following it would crash then.  Can't actually happen, because the
EventHandler thread is always runnable.  Spotted by the Clang Static

13 years agoDeclare cant_listen() noreturn
Markus Armbruster [Fri, 15 Jan 2010 19:20:36 +0000 (20:20 +0100)]
Declare cant_listen() noreturn

Local analysis can now easily find out what's up.  Before, inter-
procedural analysis was required.  The Clang Static Analyzer
complained about a dereference of res that is actually fine.

13 years agoMake CANT_HAPPEN() more obvious for static analysis
Markus Armbruster [Fri, 15 Jan 2010 19:02:11 +0000 (20:02 +0100)]
Make CANT_HAPPEN() more obvious for static analysis

Local analysis can now easily find out what's up.  Before,
whole-program analysis was required.  The Clang Static Analyzer
complained about code that is actually fine.

13 years agoFix getpath() not to crash when path exceeds MAX_PATH_LEN
Markus Armbruster [Thu, 14 Jan 2010 21:39:42 +0000 (22:39 +0100)]
Fix getpath() not to crash when path exceeds MAX_PATH_LEN

Trivial for players to trigger.  Broken in commit 0b0612ea, v4.3.16.
Spotted by the Clang Static Analyzer.

13 years agoFix oops on escort, recon, and launch of satellite
Markus Armbruster [Wed, 13 Jan 2010 20:21:58 +0000 (21:21 +0100)]
Fix oops on escort, recon, and launch of satellite

Broken in commit 528df9ac, v4.3.23.  pln_equip() recovered fine.

13 years agoUpdate copyright notice
Markus Armbruster [Sun, 10 Jan 2010 07:53:25 +0000 (08:53 +0100)]
Update copyright notice

13 years agoFix trailing whitespace
Markus Armbruster [Sun, 10 Jan 2010 07:47:40 +0000 (08:47 +0100)]
Fix trailing whitespace

13 years agoStop ship and land unit movement on interdiction with no damage
Markus Armbruster [Sat, 9 Jan 2010 15:21:40 +0000 (16:21 +0100)]
Stop ship and land unit movement on interdiction with no damage

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

* 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

13 years agoClean up poorly chosen loop control variable names
Markus Armbruster [Sat, 9 Jan 2010 13:51:59 +0000 (14:51 +0100)]
Clean up poorly chosen loop control variable names

Calling a counting loop's control variable q or z is tasteless
bordering on actively misleading.

13 years agoSimplify perform_mission()
Markus Armbruster [Sat, 9 Jan 2010 13:22:51 +0000 (14:22 +0100)]
Simplify perform_mission()

13 years agoRemove struct genlist member cp
Markus Armbruster [Sat, 9 Jan 2010 12:49:34 +0000 (13:49 +0100)]
Remove struct genlist member cp

13 years agoRemove perform_mission_land(), perform_mission_ship() parameter md
Markus Armbruster [Sat, 9 Jan 2010 12:46:33 +0000 (13:46 +0100)]
Remove perform_mission_land(), perform_mission_ship() parameter md

13 years agoSplit up perform_mission()
Markus Armbruster [Sat, 9 Jan 2010 12:26:16 +0000 (13:26 +0100)]
Split up perform_mission()

Move code out of perform_mission() into new perform_mission_land(),
perform_mission_ship(), perform_mission_msl(), perform_mission_bomb().

13 years agoMake lnd_mission_interdiction() apply damage
Markus Armbruster [Sat, 9 Jan 2010 08:44:12 +0000 (09:44 +0100)]
Make lnd_mission_interdiction() apply damage

To make lnd_mission_interdiction() work just like

13 years agoNew lnd_mission_interdiction()
Markus Armbruster [Sat, 9 Jan 2010 08:40:01 +0000 (09:40 +0100)]
New lnd_mission_interdiction()

Factored out of lnd_interdict().  No functional change.

13 years agoNew shp_mission_interdiction()
Markus Armbruster [Sat, 9 Jan 2010 08:39:15 +0000 (09:39 +0100)]
New shp_mission_interdiction()

Factored out of shp_interdict().  No functional change.

13 years agoFix att_reacting_units() to initialize ulist member eff
Markus Armbruster [Sat, 2 Jan 2010 08:27:55 +0000 (09:27 +0100)]
Fix att_reacting_units() to initialize ulist member eff

This left initial eff at zero.  No effect, because its only user
get_land() ignores efficiency increases.

13 years agoSimplify ask_olist and get_dlist() not to re-read land units
Markus Armbruster [Sat, 2 Jan 2010 08:14:55 +0000 (09:14 +0100)]
Simplify ask_olist and get_dlist() not to re-read land units

getland() is obviously redundant in get_dlist(), because the land unit
can't have changed since the previous read.

What's up with ask_olist() is less obvious.  For each capable land
unit, ask_olist() asks the player whether to attack with it.  If it
attacks, it gets copied into olist.  Since asking the player yields
the processor, these copies can become stale.  However, re-reading
fixes that just for the last one.  Moreover, the code copes with stale
copies just fine: ask_olist() is always directly followed by
att_get_offense() or att_move_in_off(), and both replace the
potentially stale copy in olist.

13 years agoRemove get_land() parameter uid
Markus Armbruster [Sun, 3 Jan 2010 20:45:10 +0000 (21:45 +0100)]
Remove get_land() parameter uid

For all remaining calls, the uid can be obtained from parameter llp.

13 years agoInline get_land()'s "first time" case into its callers
Markus Armbruster [Sat, 2 Jan 2010 07:53:25 +0000 (08:53 +0100)]
Inline get_land()'s "first time" case into its callers

ask_olist() and get_dlist() called get_land() with llp->chrp still
null, which made it initialize parts of llp instead of performing its
usual integrity check.  att_reacting_units() had the initialization
inline.  Change the other two to match, and simplify get_land().  No
functional change.

13 years agoDrop last parameter of shp_hit_mine() and lnd_hit_mine()
Markus Armbruster [Fri, 1 Jan 2010 15:55:24 +0000 (16:55 +0100)]
Drop last parameter of shp_hit_mine() and lnd_hit_mine()

13 years agoSimplify use of shp_missile_interdiction()
Markus Armbruster [Fri, 1 Jan 2010 15:38:47 +0000 (16:38 +0100)]
Simplify use of shp_missile_interdiction()

shp_missile_interdiction() does nothing when there are no suitable
targets.  Its users avoid to call it when there are none, probably to
save a few cycles.  Optimize shp_missile_interdiction() for that case,
and simplify the callers.

13 years agoMake empdump call ef_close() regardless of -n
Markus Armbruster [Fri, 1 Jan 2010 10:15:51 +0000 (11:15 +0100)]
Make empdump call ef_close() regardless of -n

Avoiding ef_close() with -n is not necessary, so don't.

13 years agoRearrange struct sctstr slightly to expose commonalities with units
Markus Armbruster [Thu, 31 Dec 2009 10:50:22 +0000 (11:50 +0100)]
Rearrange struct sctstr slightly to expose commonalities with units

Nice bonus: space needed for sectors shrinks some 4%.  Size of game
state could shrink perhaps 1-2%.

13 years agoNarrow struct sctstr member sct_mobil to char
Markus Armbruster [Thu, 31 Dec 2009 10:39:17 +0000 (11:39 +0100)]
Narrow struct sctstr member sct_mobil to char

To bring it in line with unit mobility.

13 years agoMake struct sctstr member sct_effic signed
Markus Armbruster [Thu, 31 Dec 2009 10:36:59 +0000 (11:36 +0100)]
Make struct sctstr member sct_effic signed

To bring it in line with unit efficiency.

13 years agoStreamline fortgun()'s efficiency comparison
Markus Armbruster [Thu, 31 Dec 2009 10:33:06 +0000 (11:33 +0100)]
Streamline fortgun()'s efficiency comparison

Use >= 60 instead of > 59, for consistency with similar comparisons

13 years agoFix sloppy sanity check for mobility going negative in transport
Markus Armbruster [Thu, 31 Dec 2009 10:27:48 +0000 (11:27 +0100)]
Fix sloppy sanity check for mobility going negative in transport

Assignment to sct_mobil was vulnerable to integer underflow.  Should
not happen, as move_ground() never returns a cost exceeding available

13 years agoGeneration numbers to catch write back of stale copies
Markus Armbruster [Thu, 31 Dec 2009 12:14:36 +0000 (13:14 +0100)]
Generation numbers to catch write back of stale copies

Oops when a stale copy is written back, i.e. the processor was yielded
since the copy was made.  Such bugs are difficult to spot.  Sequence
numbers catch them when they do actual harm (they also catch different
bugs).  Generation numbers catch them even when they don't.

New ef_generation to count generations.  Call new ef_make_stale() to
increment it whenever the processor may be yielded.

New struct emptypedstr member generation.  To conserve space, make it
a bit-field of twelve bits, i.e. generations are only recorded modulo
2^12.  Make sure all members of unit empobj_storage share it.  It is
only used in copies; its value on disk and in the cache is
meaningless.  Copies with generation other than ef_generation are
stale.  Stale copies that are a multiple of 2^12 generations old can't
be detected, but that is sufficiently improbable.

Set generation to ef_generation by calling new ef_mark_fresh() when
making copies in ef_read() and ef_blank().  nav_ship() and
fltp_to_list() make copies without going through ef_read(), and
therefore need to call ef_mark_fresh() as well.  Also call it in
obj_changed() to make check_sect_ok() & friends freshen their argument
when it is unchanged.

New must_be_fresh() oopses when its argument is stale.  Call it in
ef_write() to catch write back of stale copies.

13 years agoStore sequence numbers more compactly
Markus Armbruster [Thu, 31 Dec 2009 09:30:54 +0000 (10:30 +0100)]
Store sequence numbers more compactly

Store them and ef_type in bit-fields.

Allocate eight bits for ef_type.  Values range from 0 to EF_GAME
(currently 16), so this is plenty.

Allocate twelve bits for sequence numbers.  Sequence number mismatches
are now missed when the numbers are equal modulo 2^12.  Still
sufficiently improbable.

Common machines store the bit-fields in a 32 bit word.  There are
twelve bits left in that word for future use.  Total savings 16 bits,
which is exactly what the previous commit spent on wider uids on
common machines.

13 years agoStore uids as int to support more sectors and units
Markus Armbruster [Wed, 30 Dec 2009 13:07:51 +0000 (14:07 +0100)]
Store uids as int to support more sectors and units

Before, they were stored as short.  Wider uids use more space, but the
next commit will recover it by narrowing other members.

The use of short has always limited the number of ships, planes, land
units and nukes to SHRT_MAX (commonly 32768).  Only the most extreme
games ever came close.

Commit 49780e2c (v4.3.12) added struct sctstr member sct_uid to make
struct empobj member uid work for sectors.  This made the limit apply
to sectors as well.  We've had games with more than 32768 sectors.

13 years agoFix new_seqno()'s recovery from seqno mismatch
Markus Armbruster [Thu, 31 Dec 2009 11:12:39 +0000 (12:12 +0100)]
Fix new_seqno()'s recovery from seqno mismatch

A sequence number mismatch occurs when an invalid copy (with a stale
sequence number) gets written.  To continue after the error, we need
to use the current sequence number.  But new_seqno() used the larger
one of the two, which is correct only as long as sequence numbers do
not overflow.  Overflow is rather unlikely, though.

13 years agoRecord news more compactly
Markus Armbruster [Thu, 31 Dec 2009 08:18:37 +0000 (09:18 +0100)]
Record news more compactly

Member nws_uid is unused since the commit before previous.  Remove it.

Member nws_seqno is of marginal value, because we write news only
through ncache[], and thus aren't prone to the errors sequence numbers
can catch.  Remove it.

Make timestamp selector virtual, computing nws_when + nws_duration,
and remove member nws_timestamp.  Impact:

* In ncache(), the removed timestamp equals nws_when + nws_duration,
  both for new news and updated news.  No change.

* delete_old_news() becomes invisible.  Before, its move of unexpired
  news to the beginning of the news file touched all the timestamps.
  That was unwanted, because the move does not change news, only their
  storage.  Improvement.

* empdump no longer flags the imported news changed via the timestamp.
  This is somewhat unfortunate.  Document as bug.

With these members removed, struct nwsstr no longer matches struct
emptypedstr, so clear news table flag EFF_TYPED and remove union
empobj_storage member news.  This loses the automatic maintenance of
member ef_type via struct emptypedstr.  Remove ef_type as well.

This shrinks struct nwsstr from 20 to 12 bytes on common 32 bit
machines, and from 32 to 16 bytes on common 64 bit machines.  Since
the server doesn't map the whole news file (EFF_MAP is off), this
reduces I/O, while the table's memory use remains the same.

Historical note: struct nwsstr is now pretty much what it was back in
BSD Empire 1.1.  Members ef_type and nws_uid go back to Empire 3 (for
C_SYNC?).  v4.3.12 added member nws_timestamp, which doubled the size
on common 64 bit machines.  v4.3.15 added nws_seqno.

13 years agoNew news selector duration
Markus Armbruster [Thu, 31 Dec 2009 08:17:54 +0000 (09:17 +0100)]
New news selector duration

Backed by new struct nwsstr member nws_duration.  Time between first
and last occurence of the news recorded in this item, in seconds.

13 years agoRevert "Get rid of struct newscache"
Markus Armbruster [Thu, 31 Dec 2009 06:36:47 +0000 (07:36 +0100)]
Revert "Get rid of struct newscache"

This reverts commit 832574b6dee87f4efb56945c62e5d2fadec27288.

To prepare for removal of struct nwsstr member nws_uid.



13 years agoRemove unused members of struct lndstr, lonstr, nukstr, trtstr
Markus Armbruster [Wed, 30 Dec 2009 12:49:41 +0000 (13:49 +0100)]
Remove unused members of struct lndstr, lonstr, nukstr, trtstr

struct lndstr member lnd_flags is a leftover from Empire3's C_SYNC,
which was ripped out in 4.0.0.

struct lonstr member l_sel, struct nuk_str members nuk_ship, nuk_land,
and struct trtstr member trt_bond have been there basically forever
without any use.

13 years agoConsistently use int for sector and unit uid parameters
Markus Armbruster [Wed, 30 Dec 2009 11:44:01 +0000 (12:44 +0100)]
Consistently use int for sector and unit uid parameters

13 years agoConsistently use int for file type parameters and locals
Markus Armbruster [Tue, 29 Dec 2009 12:09:01 +0000 (13:09 +0100)]
Consistently use int for file type parameters and locals

13 years agoConsistently use int for mission type parameters
Markus Armbruster [Tue, 29 Dec 2009 12:06:35 +0000 (13:06 +0100)]
Consistently use int for mission type parameters

13 years agoFix launch not to wipe out target sector updates
Markus Armbruster [Sat, 26 Dec 2009 13:02:50 +0000 (14:02 +0100)]
Fix launch not to wipe out target sector updates

Launching ABMs updates their base, in mission_pln_equip().  The update
got wiped out when launch_missile() wrote back the target sector,
triggering a seqno mismatch oops.  Harmless with the stock game's
ABMs, because they use neither shells nor petrol.

Fix by re-reading the target sector.

13 years agoFix launch not to wipe out target ship updates
Markus Armbruster [Sat, 26 Dec 2009 10:28:25 +0000 (11:28 +0100)]
Fix launch not to wipe out target ship updates

Ships can expend shells to defend against missiles, in
shp_missile_defense().  Any shell use by the target ship got wiped out
when launch_missile() wrote back the target ship, triggering a seqno
mismatch oops.

Fix by re-reading the target ship.

13 years agoBump version to 4.3.24
Markus Armbruster [Sat, 26 Dec 2009 09:20:21 +0000 (10:20 +0100)]
Bump version to 4.3.24

13 years agoFix nightly build v4.3.23
Markus Armbruster [Mon, 14 Dec 2009 05:56:23 +0000 (06:56 +0100)]
Fix nightly build

Commit 5f89f8cb added pre_update.econfig with incorrect permissions.

13 years agoUpdate change log for 4.3.23
Markus Armbruster [Sun, 13 Dec 2009 16:37:13 +0000 (17:37 +0100)]
Update change log for 4.3.23

13 years agoUpdate known contributors comments
Markus Armbruster [Sun, 13 Dec 2009 14:10:07 +0000 (15:10 +0100)]
Update known contributors comments

13 years agoBelatedly update make dependencies for standalone client build
Markus Armbruster [Sun, 13 Dec 2009 07:58:07 +0000 (08:58 +0100)]
Belatedly update make dependencies for standalone client build

main.$O was out of date since commit 518c8d6f.

13 years agoDon't patch constants.c for nightly, use econfig
Ron J Koenderink [Fri, 4 Dec 2009 02:21:22 +0000 (20:21 -0600)]
Don't patch constants.c for nightly, use econfig

13 years agoFix info navigate on missile interdiction targets
Markus Armbruster [Wed, 14 Oct 2009 23:19:00 +0000 (19:19 -0400)]
Fix info navigate on missile interdiction targets

Missile interdiction targets only "valuable" ships since Empire 3.

13 years agoFix info Mobility not to claim missions get a bonus
Markus Armbruster [Wed, 14 Oct 2009 23:10:48 +0000 (19:10 -0400)]
Fix info Mobility not to claim missions get a bonus

Bonus was dropped in v4.0.0.

13 years agoMake transport chopper not light
Markus Armbruster [Wed, 14 Oct 2009 00:19:39 +0000 (20:19 -0400)]
Make transport chopper not light

Capability light has no effect for choppers since commit 041ad4ce,

13 years agoFix messages in msl_launch()
Markus Armbruster [Mon, 12 Oct 2009 02:32:44 +0000 (22:32 -0400)]
Fix messages in msl_launch()

13 years agoDon't intercept tactical and marine missiles targeting planes
Markus Armbruster [Mon, 12 Oct 2009 02:18:26 +0000 (22:18 -0400)]
Don't intercept tactical and marine missiles targeting planes

Missiles attacking ground targets (sectors, ships or land units) can
be intercepted, missiles targeting planes can't.  Except msl_launch()
checked the missile's capabilities instead of its target, and thus
intercepted missiles that *could* target ground even when they
targeted planes.

This broke the missile interception code's assumption that
interceptors aren't intercepted, and crashed the server through
infinite recursion: tactical abm #1 intercepts, tactical abm #2
intercepts #1, #1 intercepts #2, ...

Same bug in msl_hit() printed "incoming missile" for missiles that
could target ground but do target planes.

Broken in Empire 2.  Bug can't bite with the stock game's planes.

13 years agoFix and enable collateral damage for missing missiles
Markus Armbruster [Sun, 11 Oct 2009 16:04:16 +0000 (12:04 -0400)]
Fix and enable collateral damage for missing missiles

Collateral damage was disabled, because after msl_hit() reported a
miss, the missile may or may not have reached the target.

Fix by splitting msl_launch() off msl_hit().

Drop the disabled collateral damage code for sector targets, because
sectors can't be missed.  Enable it for ships and land units.

Since msl_launch() returns whether the missile is sub-launched, drop
launch_missile() parameter sublaunch, and simplify its caller.

13 years agoNews reported victim as actor for sub-launched anti-sat and ABM
Markus Armbruster [Tue, 13 Oct 2009 23:33:33 +0000 (19:33 -0400)]
News reported victim as actor for sub-launched anti-sat and ABM

If the intercepted missile was sub-launched as well, this disclosed
its owner.

The stock game's anti-sats and ABMs can't be sub-launched.

13 years agoClarify how perform_mission() uses missiles
Markus Armbruster [Sun, 11 Oct 2009 15:58:00 +0000 (11:58 -0400)]
Clarify how perform_mission() uses missiles

Interdiction of ships and land units with missiles happens elsewhere.
Oops when perform_mission() strays on that turf.

13 years agoRefactor missile interception code
Markus Armbruster [Sat, 10 Oct 2009 22:26:31 +0000 (18:26 -0400)]
Refactor missile interception code

Keep only the common part in msl_intercept(), and give it internal
linkage.  Wrap new msl_abm_intercept() and msl_asat_intercept() around
it.  They are simpler to use.

13 years agoFix defense value of intercepted missiles and satellites
Markus Armbruster [Sat, 10 Oct 2009 22:15:22 +0000 (18:15 -0400)]
Fix defense value of intercepted missiles and satellites

Use the plane's defense value, not the plane type's base value.

13 years agoFix missiles interdicting ships outside range or op area
Markus Armbruster [Sat, 10 Oct 2009 21:07:27 +0000 (17:07 -0400)]
Fix missiles interdicting ships outside range or op area

Ship interdiction works sector by sector.  Interdicting missiles
targeted all ships not yet interdicted, not just the ones in the
current sector.  This could lead to interdiction outside missile range
or op area.

13 years agoGet rid of msl_launch_mindam()
Markus Armbruster [Sat, 10 Oct 2009 20:32:18 +0000 (16:32 -0400)]
Get rid of msl_launch_mindam()

It's awkward, especially in shp_missile_interdiction().  Inline into
callers and simplify.

13 years agoSimplify control logic in msl_intercept()
Markus Armbruster [Sat, 10 Oct 2009 16:23:38 +0000 (12:23 -0400)]
Simplify control logic in msl_intercept()

13 years agoDon't attempt to hide owner of sub-launched satellite
Markus Armbruster [Sat, 10 Oct 2009 15:54:49 +0000 (11:54 -0400)]
Don't attempt to hide owner of sub-launched satellite

The attempt was pointless, because the recipient of the message could
see the owner on skywatch, and the news reported it as well.

13 years agoFix typo in info Selector
Markus Armbruster [Sat, 10 Oct 2009 15:07:29 +0000 (11:07 -0400)]
Fix typo in info Selector

13 years agoMove msl_equip() to callers, internal linkage
Markus Armbruster [Mon, 5 Oct 2009 11:27:43 +0000 (07:27 -0400)]
Move msl_equip() to callers, internal linkage

13 years agoMove "Releasing RV's" message into detonate()
Markus Armbruster [Mon, 5 Oct 2009 11:25:45 +0000 (07:25 -0400)]
Move "Releasing RV's" message into detonate()

13 years agoLimit nukes to strategic missions
Markus Armbruster [Mon, 5 Oct 2009 11:02:40 +0000 (07:02 -0400)]
Limit nukes to strategic missions

Before Empire 2, nukes could be delivered only with bomb (special
mission 'n', airburst only) and launch (targeting sectors or
satellites only).

Empire 2 made nukes available for any kind of bombing, and for any
missile strike on sectors or ships.  This included interdiction and
support missions.  Nuclear-tipped anti-sats and bomb mission n were

Unfortunately, this was done in a messy way, which led to
inconsistencies and bugs.  The problem is that ordinary damage affects
just the target, while nuke damage affects an area.  Code dealing with
plane damage was designed for the former.  Instead of rewriting it to
cope with area damage cleanly, nuke damage got shoehorned into
pln_damage(), the function to compute conventional plane damage, as a
side effect: computing damage blasted sectors in the area.

If the plane carried a nuke, pln_damage() returned zero (conventional)
damage.  Without further logic, this simply bypassed the code to apply
damage to the target.  This worked out okay when the target already
got damaged correctly by the side effect.

However, some targets are immune to the side effect: when interdicting
a move or explore command, the commodities being moved are not in any

For other targets, damage has effects other than damaging the target:
offensive and defensive support don't apply the (conventional) damage
to the target sector.  Instead, they turn it into a combat bonus.
Without further logic, nuclear damage doesn't contribute to that.

To make all that work, pln_damage() returned the nuclear damage for
ground zero as well.  Because a plane does either conventional or
nuclear damage, one of them is always zero.

Most callers simply ignored the nuclear damage, and applied only the
conventional damage.

Bug: land units and ships failed to retreat when pin-bombed or
missiled with a nuke.  That's because they received zero conventional

The mission code flies planes and missiles and tallies their damage.
This mission damage included nuclear damage at ground zero (except for
missiles sometimes, see below), to make support and commodity
interdiction work.  Unfortunately, this broke other things.

Bug: when bombers interdicted ships or land units, nukes first damaged
the ships or land units by the side effect, then again through mission
damage.  Interdicting missiles had a special case to avoid this.

Bug: when interdicting move, explore or transport, nukes first damaged
the sector by the side effect, then again through mission damage's
collateral damage.

There may well be more bugs hiding in this mess.

The mess is not worth fixing.  While the idea of interdicting and
supporting with nukes sounds kind of cool, I believe it's pretty
irrelevant in actual play.

Instead, go back to a variation of the original rules: nukes can be
delivered only through bomb mission 's' and launch at sectors.

Make arm reject marine missiles in addition to satellites, ABMs and
SAMs, and clear the mission.  Make mission reject planes armed with
nukes.  Oops when they show up in mission_pln_equip() anyway.

Make pln_equip() allow planes with nukes only for missions 's' and

Clean up pln_damage() to just compute damage, without side effect.
Change strat_bomb() and launch_missile() to detonate nukes.  Simplify
the other callers.  Parameter mission of msl_launch_mindam() is now
unused, remove it.

Missiles exploding on launch no longer set off their nukes.  That was
pretty ridiculous anyway.

13 years agoRemove unused missions from mission_pln_equip()
Markus Armbruster [Mon, 5 Oct 2009 09:46:20 +0000 (05:46 -0400)]
Remove unused missions from mission_pln_equip()

13 years agoImprove launch diagnostic messages, switch off supply
Markus Armbruster [Mon, 5 Oct 2009 09:40:39 +0000 (05:40 -0400)]
Improve launch diagnostic messages, switch off supply

msl_equip() used mission_pln_equip(), which is for automatic defenses,
and therefore silent.  Its users launch_as(), launch_missile() and
launch_sat() printed failure diagnostics based on assumptions on what
could go wrong.

Switch to the appropriate function for commands, pln_equip(), and
remove the guesswork.  Implement mission 'i' there.  When launching
from a foreign base, its owner now gets informed.  Unimportant at this
time, as players can't easily deploy missiles in foreign bases.

This change also switches off automatic supply for launch.  Consistent
with bomb.

13 years agoMake anti-sat launch consistent with interception
Markus Armbruster [Sun, 4 Oct 2009 22:42:15 +0000 (18:42 -0400)]
Make anti-sat launch consistent with interception

When a manually launched anti-sat hits, it now always destroys the
satellite.  This matches what it does when it intercepts
automatically.  Before, it only damaged the satellite.

13 years agoFix satellite interception not to break "positioned over" line
Markus Armbruster [Sun, 4 Oct 2009 22:00:14 +0000 (18:00 -0400)]
Fix satellite interception not to break "positioned over" line

13 years agoComment fix
Markus Armbruster [Sun, 4 Oct 2009 21:12:22 +0000 (17:12 -0400)]
Comment fix

13 years agoImprove message when refusing to load plane on unsuitable ship
Markus Armbruster [Sun, 4 Oct 2009 20:44:06 +0000 (16:44 -0400)]
Improve message when refusing to load plane on unsuitable ship

Test more specific causes before more general ones.  Also get rid of
silly strcpy().

13 years agoDon't permit nukes on satellites, ABMs and SAMs
Markus Armbruster [Sun, 4 Oct 2009 18:54:39 +0000 (14:54 -0400)]
Don't permit nukes on satellites, ABMs and SAMs

Before, satellites could be disarmed and armed even in orbit.  Nukes
on satellites went along into orbit, where they did nothing in

Nukes on ABMs and SAMs were lost without effect when their missile

The stock game is not affected, because its satellites, ABMs and SAMs
all have zero load.

13 years agoDrop capabilities stealth and half-stealth
Markus Armbruster [Sun, 4 Oct 2009 17:13:36 +0000 (13:13 -0400)]
Drop capabilities stealth and half-stealth

These were leftovers from Chainsaw, and their only remaining effect
was a flak bonus.

The got replaced except for flak by plane selector stealth under
Chainsaw option STEALTHV, which became mandatory in Empire 2.  It is
unclear why STEALTHV didn't cover flak.  No planes with these
capabilities have existed in the stock game since Empire 2.

13 years agoRemove redundant load checks before pln_damage()
Markus Armbruster [Sat, 3 Oct 2009 20:32:03 +0000 (16:32 -0400)]
Remove redundant load checks before pln_damage()

pln_damage() copes with any load just fine.

13 years agoSimplify how plane cargo is tracked
Markus Armbruster [Sat, 3 Oct 2009 20:25:50 +0000 (16:25 -0400)]
Simplify how plane cargo is tracked

Fold struct plist members bombs (used for bombing runs) and misc (used
for everything else) into a single member load.

13 years agoPenalize fighter combat value for any load, not just bombs
Markus Armbruster [Sat, 3 Oct 2009 20:02:17 +0000 (16:02 -0400)]
Penalize fighter combat value for any load, not just bombs

This can affect only planes with capabilities intercept and either
cargo or mine.  No such planes exist in the stock game.

13 years agoFix bomb for non-tactical cargo bomber
Markus Armbruster [Sat, 3 Oct 2009 19:57:49 +0000 (15:57 -0400)]
Fix bomb for non-tactical cargo bomber

The various bombing functions silently skipped planes not carrying
bombs.  This sanity check was wrong: it checked capabilities "tactical
or not cargo" instead of "tactical or bomber", and failed for
non-tactical cargo bombers.  No such planes exist in the stock game.
The broken check comes from Chainsaw; it replaced an equally wrong
"not cargo" check.

Because pln_sel() lets only suitable planes go on a bombing run, the
broken sanity check is unnecessary.  Drop it.

13 years agoRevise rules for cargo plane loads
Markus Armbruster [Sun, 27 Sep 2009 22:03:13 +0000 (18:03 -0400)]
Revise rules for cargo plane loads

There are three ways to fly cargo: transport (fly command with a
commodity argument), cargo drops (drop command that isn't a sea mine
drop), and paradrops.

A cargo flight can be either an airlift or an airdrop.  Airlifts carry
more cargo than airdrops.  A cargo drop or paradrop with a non-VTOL
plane is an airdrop.  Anything else is an airlift.

Before, paradrop always behaved like an airdrop, regardless of VTOL,
and drop always like an airlift.  This made little sense.

Effect of the change on the stock game: paradrop with tc carries twice
the punch, and np/tr/jt can drop less than they can fly.  In
particular, tr can't drop guns anymore, and jt can drop only one
instead of three.

13 years agoSimplify load computation in pln_equip(), mission_pln_equip()
Markus Armbruster [Sun, 27 Sep 2009 21:35:13 +0000 (17:35 -0400)]
Simplify load computation in pln_equip(), mission_pln_equip()

13 years agoSimplify plane selection for drop, fly, recon and sweep
Markus Armbruster [Sun, 27 Sep 2009 19:07:57 +0000 (15:07 -0400)]
Simplify plane selection for drop, fly, recon and sweep

Plane flying commands first select the planes to fly the mission and
their escorts, then equip them.  They all fail when no planes to fly
the mission can be equipped.

Unlike bomb and paradrop, commands drop, fly, recon and sweep had an
additional check that made them fail when no planes to fly the mission
could be selected.  Because "none selected" implies "none equipped",
the additional check is redundant.  Remove it.

While there, break lines in calls of pln_sel() more tastefully.

13 years agoMake bomb require capability bomber or tactical
Markus Armbruster [Sun, 27 Sep 2009 18:44:39 +0000 (14:44 -0400)]
Make bomb require capability bomber or tactical

Before, bomb selected any plane, but planes with zero load could not
be equipped.  Cargo planes could be equipped fine, and they flew bombs
to the target, where they silently vanished.


13 years agoMake sweep require capability sweep
Markus Armbruster [Sun, 27 Sep 2009 17:53:40 +0000 (13:53 -0400)]
Make sweep require capability sweep

Before, sweep accepted any plane.  Planes without capability sweep
flew an ordinary recon mission.

Partial fix for #1388263.

13 years agoMake drop require capability cargo
Markus Armbruster [Sun, 27 Sep 2009 17:32:34 +0000 (13:32 -0400)]
Make drop require capability cargo

Before, drop worked like fly: it accepted any plane, but planes
without capability cargo dropped nothing.

Partial fix for #1388263.

13 years agoClarify flying command info pages on plane selection
Markus Armbruster [Sun, 27 Sep 2009 17:12:36 +0000 (13:12 -0400)]
Clarify flying command info pages on plane selection

13 years agoDon't let players paradrop their own sectors
Scott C. Zielinski [Sun, 27 Sep 2009 16:39:54 +0000 (12:39 -0400)]
Don't let players paradrop their own sectors

Such a paradrop always failed, and the paratroopers were lost.

13 years agoSimplify wantflags calculation in bomb(), fly(), para(), reco()
Markus Armbruster [Sun, 27 Sep 2009 15:10:08 +0000 (11:10 -0400)]
Simplify wantflags calculation in bomb(), fly(), para(), reco()