multifire() used shots to print either shell or shells. 4.2.3 removed
its initialization for land unit fire, and commit 22c6fd8b removed it
for ship fire. Fix by just printing shells always.
Ron Koenderink [Sun, 16 Mar 2008 23:09:00 +0000 (17:09 -0600)]
Remove pre_update_hook decoration
Improve the portability. The Windows version of "echo" does
not support single quotes as a quoting character and therefore
fails and prevents updates in the Windows nightly build.
The old code let each defender fire on each target separately. To
avoid charging ammo multiple times, it didn't update the defenders
after fire; it charged them in use_ammo() instead. Bugs: not updating
the defender lost any shells fetched by automatic resupply, and
use_ammo() always charged one shell for gun fire, which was wrong for
most ships and land units.
Rewrite to let each defender fire once, updating it normally. Reuse
the damage for the other targets. This also yields the proper
probability distribution for damage.
add_to_fired_queue() adds a defender at most once. It neglects to
free the defender flist nodes it doesn't add. Broken since option
MULTIFIRE appeared in Chainsaw.
Make deffld() reject fields whose selector has flag NSC_EXTRA set.
Since xundump() doesn't provides space for these, the bug could lead
to buffer overruns.
Make sure all members of unit empobj_storage share it.
Add matching timestamp member to struct comstr, struct empobj, struct
gamestr, struct lonstr, struct natstr, struct nwsstr, struct trdstr,
struct trtstr. The timestamp isn't yet set for these. To be fixed.
Move the timestamp member to the right place in struct lndstr, struct
loststr, struct realmstr, struct nukstr, struct plnstr, struct sctstr,
struct shpstr.
empdump exports and imports game state as plain text. Limitations: it
currently can't export player bmaps, power report, telegrams,
announcements, message of the day, no-login message and log files.
Exported floating-point values may be inexact. Importing an exported
game state may not result in identical data files; besides the loss of
floating-point precision just mentioned, coordinates are normalized,
and characters beyond a string's terminating zero in a character array
are lost. Bug: importing resets timestamps to zero. It should set
them to the current time.
Don't store land unit stats in struct lndstr, part 1
New lnd_att(), lnd_def(), lnd_vul(), lnd_spd(), lnd_vis(), lnd_frg(),
lnd_acc(), lnd_dam(), lnd_aaf() replace the struct lndstr members with
the same names.
Make land unit selectors att, def, vul, spd, vis, frg, acc, dam, aaf
virtual.
Where ordinary selectors specify a value stored in some object,
virtual selectors specify a function to call to compute a value
associated with some object.
Use them to replace the special case xdump ver by new table
EF_VERSION.
Move configkeys[] to lib/common because nsc_init() needs it to
initialize empfile[EF_VERSION].cadef.
Factor out common land unit fire code into lnd_fire()
This takes care of a number of bugs / inconsistencies:
* Resupply before fire: fire command did not require unit to be in
supply, and resupplied shells. Everywhere else (return fire,
support and interdiction) the land unit had to be in supply after
resupply of everything. Unify not to resupply anything and not to
require being in supply. This is consistent with ships and sectors.
* Resupply after fire: fire command resupplied shells after active
fire. Unify not to do that. This is consistent with ships and
sectors.
* When a land unit returned fire to multiple attackers, quiet_bigdef()
charged it ammo for each one. Finally, it was charged one shell
more by use_ammo(). Except only the first land unit got charged
there in fact, because buggy add_to_fired_queue() entered only the
first land unit into the defender list. Fix add_to_fired_queue()
and change quiet_bigdef() not to charge ammo, just like for ships
and sectors. This charges only one shell instead of the true ammo
use, which is wrong, but consistent with ships.
* lnd_support() tallied support damage unrounded. Unify to round
before tally.
Factor out common torpedo fire code into shp_torp()
This takes care of a number of bugs / inconsistencies:
* Submarines with zero mobility could interdict. Change to require
positive mobility.
* Submarines with zero firing range could not interdict. Fix by
dropping the test from perform_mission(). No ships in the stock
game are affected.
* Submarines without capability torp could fire return torpedoes and
interdict. Stock sbc, nm and msb were affected by the return fire
bug. Closes bug#950936.
* Shell resupply bugs: quiet_bigdef(), fire_torp() and
perform_mission() resupplied before checking all other requirements
and could thus get more shells than actually needed.
torp() no longer resupplies shells. It's hardly worth the bother, and
fire doesn't do it either.
Fix torpedo return fire line of sight requirement and range
anti_torp() required line of sight and used gun range for all kinds of
return fire. Require line of sight only for torpedoes, not for gun
fire and depth charges. Use torpedo range for torpedoes, gun range
for gun fire and depth charges.
Factor out common ship gun fire code into shp_fire()
This takes care of a number of bugs / inconsistencies:
* Ships with zero firing range could return fire and fire support, but
not fire actively or interdict. Fix by testing for gun limit
instead in multifire() and mission(). No ships in the stock game
are affected.
* Required gun crew was inconsistent: multifire() let N military fire
max(1,floor(N/2)) guns for active fire. Ditto perform_mission() for
interdiction. quiet_bigdef() let them fire N guns for returning gun
fire. Ditto sd() for firing support and firing at boarding parties.
fire_dchrg() let them fire floor(N/2) for returning fire to
torpedoes. Unify to let N military fire floor((N+1)/2) guns.
* Shell use was inconsistent: sd() and perform_mission() used one
shell per gun, everything else one per two guns. Unify to one shell
per two guns.
* Shell resupply bugs: multifire() got two shells regardless of actual
ammo use. quiet_bigdef() got one shell (but use_ammo() uses only
one, which is a bug). sd() and perform_mission() resupplied before
checking all other requirements and could thus get more shells than
actually needed.
Before 4.0.6, depth charges required no guns, one military, did damage
like shell fire from two guns, and used two shells. Missions were not
quite consistent with that (bug). 4.0.6 changed depth charges to work
exactly like shell fire (but without updating documentation
accordingly): require guns and gun crew, non-zero firing range, scale
damage and ammunition use with guns.
Go back to the old model, but with damage like three guns, to avoid
changing the stock game's dd now (three gun damage for two shells).
Stock game's af changes from two gun damage for one shell, and nas
from four gun damage for two shells.
Factor out common depth-charging code into shp_dchrg().
Factor out common fortress fire code into fort_fire()
This takes care of a number of bugs / inconsistencies:
* sb() fired support even when there were not enough mil.
* Shell resupply bugs: multifire() and quiet_bigdef() resupplied
shells before checking all other requirements and could thus get
more shells than actually needed.
The macros defining unit stat development in tech are somewhat
inconvenient to use. Define more convenient functions, and hide away
the macros near the function definitions.
If gcc's preprocessor chokes, it leaves an empty dependency file
behind, and doesn't touch the object file. If an old object file
exists, and is newer than the .c file, make will then consider the
object file up-to-date. This can lead to nasty version errors.
delete_old_news() and init_nreport() tested for non-zero nws_when,
which is breaks for news at the epoch. Not likely to happen, but
still wrong.
ncache() tested nws_uid, which breaks for the first entry in the news
file. This made ncache() overlook that entry in the cache, and create
a new news item instead of incrementing nws_ntm. Was always broken
that way.
The call of ef_ensure_space() serves no purpose: the blank records it
adds are ignored on read, and overwritten (not updated) by new news.
Get rid of it.
Use ef_blank() when extending treaty, loan, comm and trade file
Only treaty extension initialized ef_type and uid properly. None of
them zeroed unused members and holes in the struct. comm and trade
extension called ef_extend(), which had no effect, so remove that.