Commit graph

1096 commits

Author SHA1 Message Date
24408e65b4 Clean up silly use of long in satmap()
crackle's value is betwen 0 and 100, so change it to int.
2013-05-08 06:57:54 +02:00
77f8846273 Abridge a few overly verbose declarations 2013-05-08 06:55:21 +02:00
199ea0cb39 Clean up redundant forward declarations 2013-05-08 06:55:21 +02:00
39c26f4238 Switch PRNG from BSD random() to Mersenne Twister
random() may yield different pseudo-random number sequences for the
same seed on another system.  For instance, at least some versions of
MinGW provide a random() in -liberty that differs from traditional BSD
(see commit c8231b12).  Rather inconvenient for regression testing.

MT19937 Mersenne Twister is a proven, high-quality PRNG.  Actual code
is reference code provided by the inventors[*].  Quick tests show
performance comparable to random().

Like random(), MT is not cryptographically secure: observing enough of
its output permits guessing its state, and thus its future output.  I
don't think players can do that.

Drop the copy of BSD random() we added for Windows.

Like the previous commit, this changes the server's die rolls, and
makes fairland create a different random map for the same seed.  Update
expected smoke test results accordingly.

[*] mt19937ar.sep.tgz downloaded from
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
2013-05-08 06:55:21 +02:00
54ddcd0f5a New pct_chance(), for clarity, and symmetry with chance() 2013-05-08 06:55:20 +02:00
1cf6b5e6bb Make move_ground() use roundavg()
No functional change.
2013-05-08 06:55:20 +02:00
c53158eee0 Make damage() use roundavg()
Turns damage() into a one-liner.

damage() now uses random() % 32768 in chance() instead of random() %
100 inline, therefore can round differently for the same pseudo-random
number.  Update expected smoke test results accordingly.

Aside: "random() % n" distributes evenly only when n is a power of
two.  100 isn't.  However, because random() yields at least 31 bits,
and 100 is so much smaller than 2^31, the error is vanishingly small.
2013-05-08 06:55:20 +02:00
c3be487479 Replace "roll0(N) + M" by "roll(N) + M-1" 2013-05-08 06:55:20 +02:00
866859e912 Encapsulate direct use of random(), srandom() in chance.c
Wrap roll0() around random(), and seed_prng() around srandom().  In
preparation of replacing the PRNG.
2013-05-08 06:55:20 +02:00
8eb78a5a80 Move declarations for chance.c to new chance.h 2013-05-08 06:55:20 +02:00
5507ff3116 Clean up land unit retreat chance and fix its documentation
Change chance in percent lnd_retreat - lnd_effic - 1 to lnd_retreat -
lnd_effic.  It's been that way since Empire 2, but I can't bring
myself to document the silly -1.

"info morale" wasn't updated when the retreat chance was changed in
Empire 2.  Fix that.
2013-05-08 06:55:19 +02:00
f18c46824d Clean up and document nuclear damage's chance to destroy nuke
Change chance in percent from damage-1 to damage.  It's always been
damage-1, but I can't bring myself to document the silly -1.
2013-05-08 06:55:19 +02:00
780ca1ae62 Enlarge news cache from 5 to 8 entries per country 2013-05-08 06:55:19 +02:00
5738e399c4 Make news item merging deterministic and safe for year 2038
News reporting merges news items into recent items with same contents.
For that purpuse, we keep a small cache of recent items.  When a new
item can't be merged into an item in the cache, the oldest item gets
evicted to make space for the new one.

ncache() evicts the first item with the smallest timestamp (struct
nwsstr member nws_when).  Timestamps are in seconds, therefore clashes
are common, and eviction depends on exact timing.  Such indeterminism
can make the smoke test fail.

Moreover, ncache() assumes timestamps cannot exceed 0x7fffffff.  If
they do, it always evicts the slot 0.  They will in 2038.

Fix by evicting round robin.  This always evicts the oldest item.
2013-05-08 06:55:19 +02:00
d068259487 Simplify lnd_take_casualty()'s land unit retreat code
Bonus: avoids "may be used uninitialized" compiler warnings (the code
was safe despite the warning).
2013-01-12 17:56:39 +01:00
bcff368909 Take ship cost into account when picking missile interdiction target
Due to a typo, shp_missile_interdiction() picks the admissible target
with highest efficiency instead of the one with highest efficiency *
build cost.

Broken in commit cd8d7423, v4.3.8.
2013-01-12 17:56:39 +01:00
df4925d696 Update copyright notice 2013-01-12 17:45:01 +01:00
0f1e14f0f3 Fix flying commands for destination equal to assembly point
bomb, drop, fly, paradrop, recon and sweep fail when given a
destination sector equal to the assembly point.  Broken in commit
404a76f7, v4.3.27.  Reported by Tom Johnson.

Before that commit, getpath() returned NULL on error, "" when input is
an empty path, "h" when it's coordinates of the assembly point, and a
non-empty path otherwise.

The commit accidentally changed it to return "" instead of "h".

Instead of changing it back, make it return NULL when input is an
empty path, and change bomb() & friends to accept empty flight paths.

This also affects sail: it now fails when you give it an empty path,
just like bomb & friends.  Path "h" still works.
2012-08-12 09:34:49 +02:00
efc3a8e6e2 Open journal before daemonizing, so we can fail in foreground
Just like we open server.log.  Also permits calling journal_prng()
right where we seed the PRNG.
2012-08-05 09:26:08 +02:00
324109ae45 Forbid selling units with unsalable cargo, permit selling military
Deities can customize which commodities can be sold in table item.
Default is to allow anything but civilians and military.  However,
this applies only to the commodity market, not to the unit market:
cargo of ships and land units is not restricted.

Make the two markets consistent: permit selling military by default,
forbid selling units carrying unsalable commodities.  This outlaws
selling units carrying civilians by default.
2012-07-13 20:15:34 +02:00
6c086a8110 Drop trade_desc()'s first argument 2012-07-13 20:15:34 +02:00
4f3d6792e3 Drop unclean assignments in trade_desc()
Assigning to tp->trd_owner is unclean.  Can be dropped safely, because
it has no effect: prior check_trade() drops all trades where the
assignment would change anything.
2012-07-13 20:15:34 +02:00
d9cafc156c Clean up use of union empobj_storage * as parameter type
Use it only for functions that assign objects through a pointer
parameter.  Anything else can and should use struct empobj *.
2012-07-13 20:15:33 +02:00
f75544ee70 Replace trade_check_item_ok() by check_obj_ok()
Relaxes the sanity check of the argument's ef_type.  Could be avoided,
but not worth the bother.
2012-07-13 20:15:33 +02:00
29f6d10a34 Factor check_obj_ok() out of the check_*_ok() 2012-07-13 20:15:33 +02:00
4072098c32 Drop obj_changed() parameter sz
Get size from empfile[] instead.
2012-07-13 20:15:33 +02:00
9728e68a42 Fix obj_changed() to check object exists
Relatively harmless, because these kinds of objects don't go away.
2012-07-13 20:15:33 +02:00
612ec6257d Pilots and air cargo now spread the plague
Planes flying one-way with crew or cargo spread plague from their old
base to their new base.  Planes dropping cargo spread plague from
their base to the drop's target sector.
2012-07-13 20:15:33 +02:00
bad2fd5aac Streamline plist initialization
msl_equip(), find_escorts() and perform_mission() memset() the plist,
then assign to all members but load.  Just zero load instead, like
getilists(), msl_sel() and pln_sel() do.
2012-07-13 20:15:33 +02:00
b4acb73fd1 Replace pln_oneway_to_carrier_ok() by pln_can_land_on_carrier()
Avoids reading the target ship again.
2012-07-13 20:15:33 +02:00
d9a915a05b Replace pln_onewaymission() by pln_where_to_land()
New function reads and returns target sector/ship.  Avoids reading the
target sector unnecessarily.  Callers receive the target ship, not
just its number.  Next commit will put it to use.
2012-07-13 20:14:10 +02:00
72f1e22b95 Drop could_be_on_ship()'s load count parameters
Just one caller wants them.  Inline that call, and simplify the
others.
2012-07-12 19:52:33 +02:00
665d0d723d Inline fit_plane_on_ship() and fit_plane_on_land()
Just one call site each.
2012-07-12 19:52:33 +02:00
b60e5be22c Don't let planes fly to a carrier without sufficient space
We test whether the the carrier has space for each plane individually
instead of whether it has space for all of them.  The planes that fit
land, the others abort and get teleported home.  Abusable.

pln_oneway_to_carrier_ok() was created in commit 1127762c (v4.2.17) to
fix almost the same bug.  It worked fine then, because
fit_plane_on_ship() worked with load counters, and incremented them.

Broken in commit 3e370da5 (v4.3.17), which made fit_plane_on_ship()
count the loaded planes, to permit the removal of load counters.  But
unlike load counters, loaded planes don't change during
pln_oneway_to_carrier_ok().  Thus, each plane is checked individually.

Fix by tallying all the planes before checking for space.
2012-07-12 19:51:57 +02:00
81efebd367 Factor inc_shp_nplane() out of could_be_on_ship() 2012-06-24 08:49:57 +02:00
ae279968b9 Factor ship_can_carry() out of could_be_on_ship() 2012-06-24 08:49:57 +02:00
f11071f3b7 Let march sub-command 'm' sweep own and allied landmines 2012-06-11 17:28:19 +02:00
0b7fba038a Land units no longer sweep allied landmines
They don't hit them since commit fe372539, v4.3.27.  Sweeping was
forgotten then.

Closes #717591.
2012-06-11 17:28:14 +02:00
150b2c5165 Fix bmap commands not to parse empty flags argument as "revert"
Broken in commit a00f9e20, v4.3.27.
2012-06-11 17:02:15 +02:00
1118f1c0ca Update copyright notice 2012-06-10 10:52:22 +02:00
ea94ec2f18 Disable damage to base when missile explodes on launch
When a missile explodes on launch, it has a 33% chance to damage its
base.

Unfortunately, damaging the base breaks callers that call msl_launch()
for each member of a list of missiles created by msl_sel() or
perform_mission().  Damage to the base can damage other missiles
there.  Any copies of them in the list become stale.  When
msl_launch() modifies and writes back such a stale copy, the damage
gets wiped out, triggering a seqno oops.

Affects missile interdiction and interception using missiles with
non-zero load.  Stock game's ABMs have zero load, so interception is
safe there.  Relatively harmless in practice.  Broken in Empire 2.

Instead of fixing the bug, simply disable damage to the base for now.
2012-05-22 20:56:47 +02:00
0dd59211aa Fix march not to wipe out concurrent updates
March code reads the land units into a land unit list, and writes them
back when it changes them, e.g. when a land unit stops.  If a land
unit changes in the land unit file while it is in such a land unit
list, the copy in the land unit list becomes stale, and must not be
used.

To that end, do_unit_move() calls lnd_mar() after prompting for path
or destination.  lnd_mar() re-reads all the land units.
Unfortunately, it still writes back stale copies in certain
circumstances.  Known ways to trigger such writes:

* Deity loads land unit onto a ship or land unit

* Land unit's crew killed just right, e.g. by collateral damage from
  interdiction, followed by additional updates, such as shell fire
  damage

* Sector no longer owned or allied, e.g. allied sector captured by an
  enemy (own sector would kill or retreat the land unit)

Writing a stale copy wipes out the updates that made the copy stale,
and triggers a seqno mismatch oops.  For instance, damage that follows
killing of all crew by collateral damage from interdiction is wiped
out.  If no damage follows, we still get a generation oops.
2012-05-22 20:38:19 +02:00
a694e49343 Fix navigate not to wipe out concurrent updates
Navigation code reads the ships into a ship list, and writes them back
when it changes them, e.g. when a ship stops.  If a ship changes in
the ship file while it is in such a ship list, the copy in the ship
list becomes stale, and must not be used.

To that end, do_unit_move() calls shp_nav() after prompting for path
or destination.  shp_nav() re-reads all the ships.  Unfortunately, it
still writes back stale copies in certain circumstances.  Known ways
to trigger such writes:

* Deity sets a sail path

* Ship's crew gone, e.g. killed by shell fire

* Sector no longer navigable, e.g. harbor shelled down, or bridge
  built

Writing a stale copy wipes out the updates that made the copy stale,
and triggers a seqno mismatch oops.  For instance, ship damage that
kills all crew while the ship is being navigated gets wiped out.
2012-05-22 20:38:19 +02:00
786e2a99d5 Clean up superfluous includes 2012-04-26 19:57:19 +02:00
1a97cc3cfd Separate login_grace_time from max_idle
max_idle applies in state PS_PLAYING, login_grace_time before (login,
state PS_INIT) and after (logout, state PS_SHUTDOWN).

Cut login_grace_time to two minutes, from max_idle's 15.  Two minutes
is plenty to complete login and logout.  Makes swamping the server
with connections slightly harder, as they get dropped faster.  While
that makes sense all by itself, the real aim is making increasing
max_idle safe.  The next commit will complete that job.
2012-04-26 19:57:19 +02:00
cac506f664 Fix pr_player() and upr_player() to obey max_idle
The output queue flush can block indefinitely.  Permits a client to
hog the thread indefinitely by not reading output.

Broken in commit 08b94556 (v4.3.20) "Reimplement max_idle without a
separate thread".  Until then, the idle thread aborted a stuck attempt
to flush output.

Denial of service seems possible.
2012-04-26 19:43:42 +02:00
7980465199 Factor player_output_some() out of pr_player(), upr_player() 2012-04-26 19:43:42 +02:00
7a3cbf037a Add deadline support to io_output(), io_output_if_queue_long()
Replace parameter wait by deadline.  Non-zero wait argument becomes
(time_t)-1 argument, zero wait argument becomes zero deadline
argument.  No functional change, yet.
2012-04-26 19:43:22 +02:00
68dc9b2936 Fix uninitialized variable use in defending land unit retreat
lnd_take_casualty() uses uninitialized rsect to compute the mobility
cost of retreating a defending land unit.  This can charge incorrect
mobility, prevent retreat, or, if the stars align just right, crash
the server when sector_mcost() subscripts dchr[] with it.

Broken in commit 4e7c993a, v4.3.6.  Reported by Scott C. Zielinski.
2012-03-05 12:57:52 +01:00
330f8ca567 Fix 'm' in path argument of explore, move, transport
Two related bugs:

* It moans about deprecated argument syntax ('m' without a space
  before its argument) even when there's no argument.

* It uses the third instead of second argument for map flags (second
  argument is ignored): "m# s" doesn't show ships, and "m# s p" shows
  planes instead of ships.

Broken in commit 28d48474, v4.3.27.
2012-02-21 18:11:23 +01:00