A group retreat is executed in increasing UID order. The resulting
bulletin can be confusing.
Instead, retreat the ship that had its retreat conditions satisfied
first, and only then its group, if any.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The mission gets cleared whenever a retreat is triggered, even for
ships and land units that are unable to retreat.
Clear it only when the ship or land unit actually retreats.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
retreat_land() reads ships instead of land units, overrunning local
variable land. On lucky systems such as mine, this clobbers ni, and
triggers an oops. On unlucky systems, it crashes. On really unlucky
systems, it corrupts the land units file.
Broken since land unit retreat was added in Chainsaw 3.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
With EASY_BRIDGES off, bridge spans need to be next to a bridge tower
or a bridge head that is at least 20% efficient to remain standing.
When a bridge tower or head gets damaged below 20%, adjacent spans may
lose support. Bug: they don't fall when they're next to another
bridge head below 20%.
Has always been broken.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
With EASY_BRIDGES on, bridge spans need to be next to land or a bridge
tower to remain standing.
Land can't go away, but a bridge tower can fall. Bridge spans next to
it may lose support then. Bug: they don't fall when they lose support
that way. Fix that.
Broken in commit 40eb78e, v4.3.12.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
bridgefall() wants to do this:
for all possible pairs of directions (i, j)
if i and j cancel out
continue
do stuff
It does it by adding direction offsets to start coordinates, and
comparing the resulting coordinates to the start coordinates. Fine,
except it neglects to normalize the resulting coordinates.
Harmless in practice, because you can get an incorrect result only
when the path goes around the world, which it can do only in a 4x2
world.
Fix it anyway, by testing "directions cancel out" directly.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
TREATIES has issues:
* Treaties can cover attack, assault, paradrop, board, lboard, fire,
build (s|p|l|n) and enlist, but not bomb, launch, torpedo and
enlistment centers.
* Usability is very poor. While a treaty is in effect, every player
action that violates a treaty condition triggers a prompt like this:
This action is in contravention of treaty #0 (with Curmudgeon)
Do you wish to go ahead anyway? [yn]
If you decline, the action is not executed. If you accept, it is.
In both cases, your decision is reported in the news.
You cannot get rid of these prompts until the treaty expires.
* Virtually nobody uses them.
* Virtually unused code is buggy code. There is at least one race
condition: multifire() reads the firing sector, ship or land unit
before the treaty prompt, and writes it back after, triggering a
generation oops. Any updates made by other threads while trechk()
waits for input are wiped out, triggering a seqno mismatch oops.
* The treaty prompts could confuse smart clients that aren't prepared
for them. WinACE isn't, but is reported to work anyway at least
common usage. Ron Koenderink (the WinACE maintainer) suspects there
could be a few situations where it will fail.
This feature is not earning its keep. Remove it. Drop command
treaty, consider treaty, offer treaty, xdump treaty, reject treaties.
Output of accept changed, obviously.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Bug bites when a ship supplies the sector it's in. First the sector
is charged zero mob for moving the stuff, and is written back. Next,
the sector receives the stuff, and is written back, clobbering the
first write (no effect), and triggering a seqno oops.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Breaking sanctuary turns 100% sanctuaries into capitals, all others
into highways. Before Empire 3, sanctuaries always became capitals.
Give deities more control over initial state of countries than
choosing between 100% capital and <100% highway sectors: turn
sanctuaries into their new designation on break. Except make a
capital when the new designation is sanctuary (which it normally is).
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Print a message, send bulletin to owner. Affects ship key 'W', land
unit key 'W', and plane key 'f'. The message is necessary to give the
deity a chance to catch unexpected changes, e.g. a player modifying
retreat conditions right before the deity edits them. Watching out
for such changes is especially important with non-interactive edit.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Edit lets deities load units onto remote carriers, resulting in a
carriers having cargo in another sector. Not good. Cargo gets
teleported to its carrier belatedly when the carrier moves.
Better let edit take care of the teleport.
Also tell the deity that he just caused a teleport. Necessary to give
the deity a chance to catch unexpected changes, e.g. a player moving a
plane right before the deity edits it. Watching out for such changes
is especially important with non-interactive edit.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Print a message, send bulletin to owner. Affects plane keys 's', 'y',
and land unit keys 'S', 'Y'. The message is necessary to give the
deity a chance to catch unexpected changes, e.g. a player loading a
plane right before the deity edits it. Watching out for such changes
is especially important with non-interactive edit.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Print "unchanged" instead of "changed from X to X". Affects edit,
setresource, setsector. Suppress bulletin and news. Affects only
edit sector key 'L'.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Send bulletin to owner and report news exactly like for key 'o'.
Also print a "sector duplicated" message, just for consistency with
other keys.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
cname() calls getnatp(), and returns a null pointer when it fails.
Some systems (GNU, Windows) deal gracefully with printing null
strings, others crash.
Because we keep table EF_NATION entirely in memory, getnatp() should
fail only on invalid country number.
Rewrite prnatid() to catch this error and recover.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Land unit coordinates run into efficiency in output of satellite when
the y coordinate is wider than three characters. Broken in Empire 2.
Restore the separating space.
Both ship and land unit table header aren't aligned with the table
body. Affects recon and sweep with spy planes, and satellite. Fix
the header.
Reported-by: William Fittge <ptkei2@gmail.com>
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
nstr_parse_val() interprets argument "" as (empty) identifier, then
returns a pointer right beyond the end of the string.
The argument points into player->argbuf[]. If another argument
follows the conditional, it gets appended to the conditional. Else,
whatever's left there from previous commands gets appended. If the
argument is at the very end of player->argbuf[], we parse beyond the
buffer, until we run into a syntax error, or a zero byte.
Since player->argbuf[] is followed by a bunch of pointers, a syntax
error is almost certain. If we somehow manage to parse all the
pointers and player->lasttime, the runaway parse will end at
player->btused, because that's definitely zero when conditionals get
parsed.
The fire command requires at least one gun for depth charging, but
missions and return fire don't. Has always been that way, except
between 4.0.6 and commit a3ad623 (v4.3.12), when depth charging worked
exactly like gun fire, and guns were consistently required.
Require guns for all ways to drop depth charges.
Code dealing with money mixes int and long pretty haphazardly.
Harmless, because practical amounts of money fit into int on any
machine capable of running the server. Clean up anyway.
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
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.
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.