Commit graph

1017 commits

Author SHA1 Message Date
162158fd4a Fix loading x-light missiles on ships without capability plane
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.
2010-05-09 09:08:04 +02:00
265bd0c56b Update bmap when nuclear detonation makes wasteland
detonate() tells the player the new sector designation (wasteland or
sea) when damage exceeds 100.  But it neglected to update the bmap.
Fix that.
2010-05-09 09:08:04 +02:00
b97d0c625e Simplify detonate() for nukes falling on water 2010-05-09 09:08:04 +02:00
d7671e297a Fix harmless seqno mismatch in launch
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.
2010-05-09 09:08:03 +02:00
6de86720b2 Fix fly and drop to report discarded cargo items correctly
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.
2010-05-09 09:08:03 +02:00
7506039f1b Fix test for capability engineer in lnd_hit_mine()
Bogus array index, unpredictable result, can crash the server.  Broken
in commit ef7ea893, v4.3.24.
2010-04-07 23:35:25 +02:00
162435e690 Clean up checks for zero value of pln_damage()
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.
2010-04-02 19:08:27 +02:00
054eba7a1d Fix test for capability sweep in shp_hit_mine()
Bogus array index, unpredictable result, can crash the server.  Broken
in commit ef7ea893, v4.3.24.
2010-03-21 09:26:37 +01:00
ce51816d00 Comment fix 2010-03-20 18:46:02 +01:00
1d4fea32b8 Fix interdiction 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 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.
2010-03-20 18:44:45 +01:00
876f3424b0 Nuclear-tipped missile exploding on launch could not damage base
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.
2010-03-16 21:28:08 +01:00
3a9d27186c Don't print Blam-blam when missile explodes on launch 2010-03-16 21:28:07 +01:00
2dd97dbd00 Interdiction attacked submarines with surface-only weapons
shp_mission_interdiction() used MI_INTERDICT instead of MI_SINTERDICT.
Broken in commit cd8fe31e, v4.3.24.
2010-03-10 09:41:10 +01:00
b8f5eaff0b Clean up dead stores
Does not change optimized code (gcc -O).

Spotted by the Clang Static Analyzer.
2010-01-19 08:40:42 +01:00
ad80846283 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.
2010-01-19 08:40:17 +01:00
9b62b35424 Fix oops on escort, recon, and launch of satellite
Broken in commit 528df9ac, v4.3.23.  pln_equip() recovered fine.
2010-01-19 08:40:17 +01:00
73e25ff21e Update copyright notice 2010-01-19 08:40:17 +01:00
227854bca2 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
  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.
2010-01-19 08:38:18 +01:00
05b56fa942 Clean up poorly chosen loop control variable names
Calling a counting loop's control variable q or z is tasteless
bordering on actively misleading.
2010-01-19 08:38:16 +01:00
3ce3b2e387 Simplify perform_mission() 2010-01-19 08:38:16 +01:00
5e77193cf0 Remove struct genlist member cp 2010-01-19 08:38:16 +01:00
2e69a24402 Remove perform_mission_land(), perform_mission_ship() parameter md 2010-01-19 08:38:16 +01:00
d471d684be Split up perform_mission()
Move code out of perform_mission() into new perform_mission_land(),
perform_mission_ship(), perform_mission_msl(), perform_mission_bomb().
2010-01-19 08:38:16 +01:00
0706836708 Make lnd_mission_interdiction() apply damage
To make lnd_mission_interdiction() work just like
shp_mission_interdiction().
2010-01-19 08:37:07 +01:00
f8e7fb8ca8 New lnd_mission_interdiction()
Factored out of lnd_interdict().  No functional change.
2010-01-19 08:37:05 +01:00
cd8fe31eda New shp_mission_interdiction()
Factored out of shp_interdict().  No functional change.
2010-01-19 08:37:05 +01:00
d4f1e02273 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.
2010-01-19 08:37:05 +01:00
ec75a407c7 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.
2010-01-19 08:37:05 +01:00
ba0d4d0036 Remove get_land() parameter uid
For all remaining calls, the uid can be obtained from parameter llp.
2010-01-19 08:37:05 +01:00
b824495bad 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.
2010-01-19 08:37:05 +01:00
ef7ea8934f Drop last parameter of shp_hit_mine() and lnd_hit_mine() 2010-01-19 08:37:05 +01:00
a90b3e8819 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.
2010-01-19 08:37:05 +01:00
aa659c7754 Narrow struct sctstr member sct_mobil to char
To bring it in line with unit mobility.
2010-01-19 08:37:05 +01:00
76575df96b Streamline fortgun()'s efficiency comparison
Use >= 60 instead of > 59, for consistency with similar comparisons
elsewhere.
2010-01-19 08:37:05 +01:00
2fa5f65257 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.
2010-01-19 08:36:01 +01:00
358aee203e 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.
2010-01-19 08:31:10 +01:00
0ba61f1714 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.
2010-01-19 08:21:56 +01:00
b719f39c0f 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.
2010-01-19 08:21:55 +01:00
39114987a9 Revert "Get rid of struct newscache"
This reverts commit 832574b6de.

To prepare for removal of struct nwsstr member nws_uid.

Conflicts:

	src/lib/subs/nreport.c
2010-01-19 08:21:55 +01:00
d8c940ec2c Consistently use int for sector and unit uid parameters 2009-12-31 09:45:56 +01:00
c0ed527311 Consistently use int for file type parameters and locals 2009-12-29 17:23:22 +01:00
60519b3cd0 Consistently use int for mission type parameters 2009-12-29 13:06:35 +01:00
c528fcbe3e Update known contributors comments 2009-12-13 17:34:28 +01:00
2178aa87f9 Fix messages in msl_launch() 2009-12-13 08:19:52 +01:00
22071b4edb 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.
2009-12-13 08:13:29 +01:00
fd894d9864 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.
2009-12-13 08:05:26 +01:00
e7fec28009 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.
2009-12-13 08:05:25 +01:00
4dbee9a388 Clarify how perform_mission() uses missiles
Interdiction of ships and land units with missiles happens elsewhere.
Oops when perform_mission() strays on that turf.
2009-12-13 08:04:08 +01:00
0060e48ea4 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.
2009-12-13 08:04:07 +01:00
de2fae0ee6 Fix defense value of intercepted missiles and satellites
Use the plane's defense value, not the plane type's base value.
2009-12-13 08:04:07 +01:00