There were two checks meant to enforce positive numbers, both dating
back to the earliest known versions of the code, and both wrong.
The first one applied only to thresholds given with the command, not
ones prompted for, and it incorrectly rejected numbers starting with +
or prefixed by whitespace. Remove it.
The second one failed to reject negative numbers when prefixed by
whitespace. Fix.
Fortunately, the update doesn't conjure up stuff to satisfy negative
thresholds.
The old code didn't return RET_SYN when aborting at the following
prompts:
* designate second argument
* morale second argument
* route second argument
* set third argument
* tend fourth argument
* zdone last argument
Fail the command when the designation isn't allowed for mortals, or
when the player can't afford it.
Treat '=' and '@' like the other designations not allowed for mortals,
not like invalid designations. Change failure for invalid designation
from RET_FAIL to RET_SYN.
bdes() failed to do that when the player aborted at the prompt for the
new designation.
desi() failed to do it when it failed the command because the new
designation was bad.
Before failing the command, the old code attempted to change the
current sector's distribution center to the last one used, which might
have been uninitialized coordinates. If lucky, the coordinates were
invalid, and the attempt oopsed and did nothing.
The old code didn't honor command abortion at the following prompts:
* arm third argument
* deliver fourth argument (also simplify)
* fire third argument
* fly and recon prompt for carrier to land on: pln_onewaymission()
treated abort like empty input, which made planes attempt landing in
the sector.
* lmine second argument
* order d fourth argument
* power c nat(s) argument
* range second argument
* sail second argument
* shutdown both arguments (first one was broken in commit 84cfd670,
v4.3.10, second one never worked).
* tend third argument
fly() reads the carrier, then passes it to pln_dropoff(), which writes
it back. fly() also calls pln_oneway_to_carrier_ok(), which updates
the carrier when its plane summary information is incorrect.
The old code called it between reading the carrier and passing it to
pln_dropoff(). This made pln_dropoff() wipe out the plane summary
update, and triggered a seqno mismatch oops. Broken by introduction
of pln_oneway_to_carrier_ok() in commit 1127762c, v4.2.17.
Fix by reading the carrier right before passing it to pln_dropoff().
Change retreat condition prompt to point to help. Before, it listed
conditions rather cryptically, without mentioning how to get help.
Don't provide help when encountering a bad retreat condition
character.
Fail the command when encountering a bad retreat condition character.
Before, they were dropped.
Don't fail the command when the player asks for help at the condition
code prompt.
Retreat condition help failed to explain 'c'.
The old code recognized group retreat only when the first argument was
on the command line. Didn't make a difference, because it was only
used when there were at least two arguments on the command line.
The old code relied on rflags being represented as two's complement.
When given an empty retreat path, the old code deleted the retreat
path and set the retreat flags normally. The new code deletes both.
Neither is nice; it should perhaps keep the retreat path and only set
the flags.
Spies shot were only deduced from sector military; land units were
immune to losses; in fact they needn't have any military to spy.
Fix by requiring and using only sector military. Closes#758483.
Make spy() not skip sectors without civilians, military and land
units. There could be other interesting things to report there:
efficiency, gold bars, planes...
The values in these columns were computed by count_sect_units() and
count_sect_planes(), which included land units and planes in the count
that aren't shown by prunits() and prplanes(), namely own and embarked
units. Confusing. Moreover, count_sect_planes() and prunits() rolled
dice separately for spy units. This could leak the presence of spies
even when prunits() didn't show them.
All fixable, but not worth the trouble; just remove the counts.
Firing damage reduction for range is a feature that was always there
and never really documented. Different ways to fire reduced damage
differently for range, or not at all. Fix that by dropping the
reduction everywhere.
The reduction happened randomly, with probability p = (d/m)^2, where d
is the distance to the target, and m is the maximum firing range. The
fire command printed "Wind deflects shells" when it happened.
The old fire command (before MULTIFIRE) either halved damage (50%
chance), or reduced it by a factor of 1-p.
MULTIFIRE's fire command halved damage. v4.0.2 reduced that loss to
10-20%.
Interdiction halved damage, but only when firing from ships.
Other ways to fire (support, return fire, interdiction from forts and
land units) did not reduce damage for range.
People can be delivered since v4.0.0 (the check that disabled that was
commented out), and cutoff shows these deliveries since v4.0.2. The
change was documented in info Empire4, but info pages weren't updated.
Do that, and remove the commented out code.
This oopses on output dependency violations, e.g. two threads doing a
read-modify-write without synchronization, or the one thread nesting
several read-modify-writes. Such bugs are difficult to spot, and tend
to be abusable. I figure we have quite a few of them.
New struct emptypedstr member seqno. Make sure all members of unit
empobj_storage share it. Initialize it in files: main() and
file_sct_init(). Set it in ef_blank() and new ef_set_uid() by calling
new get_seqno(). Use ef_set_uid() when copying objects: swaps(),
doland(), doship(), doplane(), dounit(), delete_old_news(). Step it
in ef_write() by calling new new_seqno().
Factor do_read() out of fillcache() to make it available for
get_seqno().
The abstract idea of tying ships and land units to a logistical tether
is sound, the concrete implementation as option FUEL is flawed. It
adds too much busy-work to the game to be enjoyable. It hasn't been
enabled in a public game for years. The code implementing it is ugly,
repetitive, and a burden to maintain.
Remove selector fuel from ship_ca[] and land_ca[], and selectors
fuelc, fuelu from mchr_ca[] and lchr_ca[]. Remove fields fuelc, fuelu
from ship.config and land.config.
Remove command fuel from player_coms[].
Deprecate edit key 'B' in doship(), dounit(), and don't show it in
pr_ship(), pr_land().
Drop opt_FUEL code from build_ship(), shi(), sdump(), ship_damage(),
show_ship_stats(), do_mob_ship(), nav_ship(), build_land(), land(),
ldump(), land_damage(), show_land_stats(), do_mob_land(),
resupply_all(), resupply_commod(), get_minimum(), has_supply(),
unit_list(), vers().
Remove opt_FUEL, fuel_mult, struct shpstr member shp_fuel, struct
mchrstr members m_fuelc and m_fuelu, M_OILER, struct lndstr member
lnd_fuel, struct lchrstr members l_fuelc and l_fuelu, fuel(), and
auto_fuel_ship().
pin_bomb() computed the number of foreign subs as number of ships less
number of foreign surface ships. This counted own surface ships as
subs.
Change it to count foreign subs directly. Closes#906040.
However, shipsatxy(), the function for counting foreign ships, also
lists them. Add a parameter to suppress that, and change its callers.
Make caploss() transfer money, loans and market lots to the player
only if he actually took the capital, not if he obliterated it to
deity.
To make this work, caploss() needs to be called after the sector is
updated for damage and change of ownership. Change callers
accordingly.
Closes#914049.
Don't call bsanct() when desi() is redesignating a sanctuary. It's
pointless, because only deities can redesignate sanctuaries, and
bsanct() does nothing for them.