Damage due to lack of maintenance is now limited by the unit's minimum
efficiency.
Before, units could die. Unfortunately, the update left any embarked
units on their dead carrier. Should have seen this when I fixed a
related bug in commit c2c0d1ff, v4.3.22. Broken for ships and land
units when Empire 2 added their maintenance cost, and for planes when
commit 2e40a4bb (v4.3.4) replaced nuclear stockpiles by nuke units.
The common root cause of these bugs is the update bypassing pre-write
functions (bug#1010856).
If another unit with the same number got built, it picked up the stuck
cargo, triggering the oops from commit 6fb5caf6, which see.
In "stuck on dead carrier" state, units pretty much behave as if their
carrier was still alive, with additional protection from the fact that
a dead carrier can't be damaged or boarded.
The server detects this state on startup since commit 7da9aab5, and
refuses to start.
Only a deity can take units off a dead carrier.
Spy units are now enabled when a land unit type with capability spy
exists. To disable them, deities have to customize table land-chr.
Before, spy units types were ignored when option LANDSPIES was
disabled. Except for xdump land-chr, which happily dumped unusable
spy unit types.
Trade ships are now enabled when a ship type with capability trade
exists. No such type exists by default; to enable trade ships,
deities have to customize table ship-chr.
Before, trade ship types were ignored when option TRADESHIPS was
disabled. Except for xdump ship-chr, which happily dumped unusable
trade ship types.
Add bug reporting instructions.
Drop the bugs documented as fixed. File was last changed in Empire 2,
so these have been fixed for a while...
Remaining bugs:
The classification scheme used by report is dumb.
It still is.
You can make a sector temporarily useless by filling up all its
fields with delivery and distribution information. This is useful
when an enemy is trying to capture the sector (his mil don't have
room to move in :-) You have to halt some of the deliveries or
distributions to make room for the military to move in. (Mostly
fixed by changing the number of available fields)
Fixed since 4.2.14 eliminated `variables'. Delete.
Warehouses can't distribute all commodities simultaneously, due to
limited fields for this information. This becomes a problem if
you have a countrywide network of warehouses distributing to each
other. (Mostly fixed by changing the number of available fields)
Fixed since 4.2.14 eliminated `variables'. Delete.
You can sometimes move small quantities of certain items from
warehouses at no mobility cost, even into mountains (this is my
favorite bug, I'd hate to see it fixed :-)
Feature; delete.
Guerrillas don't seem to carry the plague.
They still don't.
You can sometimes trick someone into paying a huge price for
commodities by changing the price suddenly. Therefore one should
always check prices when buying commodities.
You can't increase prices anymore. Delete.
When two countries are attacking each other simultaneously, you
can sometimes move into a sector he is in the process of
attacking. If you get the timing right, he will take the sector
but you will get it back, along with all his military.
Can't reproduce; delete.
If a plane is out to trade, and gets shot down, it can still be
bought until the next update. If another country builds a new
plane that gets the number of the plane that was shot down, the
new plane will go on the trading market automatically. Then if
that plane is bought, the money goes to the country whose plane
was shot down, not the country that built the plane. I stole
numerous planes (including nuclear missiles :-) this way (by
deliberately putting low numbered planes up for trade, then having
them shot down).
Planes on a trading block can't get shot down, because they can't fly.
They can get destroyed on the ground, though. A new plane with the
same number still goes on the market automatically. Same for ships,
land units and nukes. check_trade() deletes a trade when the object's
owner changed. Reword the paragraph accordingly.
If a plane has negative mobility, then gets traded, mobility goes to 0.
Still correct.
Firing on sectors with land-locked sunken ships does strange
things.
Can't reproduce; delete.
If two countries are cooperating, its possible to raid an enemy
airport and steal the planes by putting them out to trade.
Still correct.
You can also strip enemy sectors of commodities using "sell", if
you have military control temporarily.
Requires mobility now. Delete.
One can make work go back to 100 everywhere in a country by moving
all civil- ians in low-work sectors onto a bridge, then collapsing
the bridge. Work then goes to 100 at the next update, if you
leave some mil in the vacated sectors. Or you can move mil out
too, letting the sector ownership change to the Deity, then move
back in from a 100% working sector, and work goes immediately to
100.
Feature; delete.
Two cooperative countries can move commodities around at no
mobility cost using the market.
Still correct.
You can collapse enemy bridges by making a lightning raid on his
bridgeheads and redesignating them, even if you only hold the
bridgehead for a short time. (In this games, bridges work
differently, see info build, info bridges")
Still correct. The parenthesis is cryptic, though; delete it.
You can map out enemy territory by raiding his radar stations.
Feature; delete.
Condition checking is very treacherous. Global commands with
conditions are unreliable. I never figured out exactly what was
wrong, although I think your method of putting conditions towards
the front of the line helped sometimes.
Can't reproduce; delete.
You can have more than 26 ships in a fleet, but only the first 26
will move when you navigate the fleet (I think 26 is the right
number, but I'm not cer- tain. It might be 32).
Can't reproduce; delete.
"Look" only spots subs (from destroyers) at a certain distance.
If you are too close you won't see them (unless you are in the
same sector).
Can't reproduce; delete.
You can only fly as many planes on a mission as you can fit on the
command line (so low numbered planes have an advantage this way).
USE WINGS
The real issue here is truncation of long input lines. Replace.
When a sector has a visible ship, radar doesn't show whether the
sector is land or sea, just the ship. This has interesting
possibilities for exploita- tion (like land-locking a battleship
in your capital in order to deceive the enemy :-)
Feature; delete.
I don't think you can land planes on a land-locked aircraft
carrier anymore.
Yes, you can. Is that good or bad? Anyway, delete.
Its common to mistakenly set the price of a plane or ship
incorrectly so one should check trade after using set.
Pilot error; delete.
The "must be accepted by" date on offered loans is bogus.
Why is it bogus? The date looks good to me. The offer expires at
that time. Delete.
"Turn off" doesn't stop updates.
Feature; delete.
parse_map_flags() silently truncates map flags after the first 't' or
'r'. This makes it accept arguments "true" and "revert". However, it
also breaks the perfectly sensible argument "ts", which should show
ships just like "st", but doesn't.
info bmap & friends document arguments "true" and "revert", and also
suggest flags 't' and 'r'. What a mess.
Make argument "revert" a special case. Deprecate flag 'r', and clean
up truncation there.
Don't truncate after flag 't'. If any bad flags follow, ignore
everything after 't', but deprecate that usage.
Drop .SY for map commands other than the one documented by the info
page.
Use the page's command to discuss arguments "revert" and "true", not
"bmap".
Clarify flags argument.
It misuses snxtsct() and snxtitem() to find out whether the first
argument looks like sectors or like ships, which doesn't work with a
bad conditional argument.
Not worth fixing now; it's been disabled since 4.0.1, and broken at
least since commit 2fc1e74a (v4.3.0) broke its sector/ship
disambiguation via third argument.
Why upgrade? I'm not a lawyer, but here's my take on the differences
to version 2:
* Software patents: better protection against abuse of patents to
prevent users from exercising the rights under the GPL. I doubt
we'll get hit with a patent suit, but it's a good move just on
general principles.
* License compatibility: compatible with more free licenses, i.e. can
"steal" more free software for use in Empire. I don't expect to steal
much, but it's nice to have the option.
* Definition of "source code": modernization of some details for today's
networked world, to make it easier to distribute the software. Not
really relevant to us now, as we normally distribute full source code.
* Tivoization: this is about putting GPL-licensed software in hardware,
then make the hardware refuse to run modified software. "Neat" trick
to effectively deny its users their rights under the GPL. Abuse was
"pioneered" by TiVo (popular digital video recorders). GPLv3 forbids
it. Unlikely to become a problem for us.
* Internationalization: more careful wording, to harden the license
outside the US. The lawyers tell us it better be done that way.
* License violations: friendlier way to deal with license violations.
This has come out of past experience enforcing the GPL.
* Additional permissions: Probably not relevant to us.
Also include myself in the list of principal authors.
SLOW_WAR has issues:
* The check whether the attacker old-owns the attacked sector is
broken, because att_abort() uses sect.sct_oldown uninitialized.
Spotted by the Clang Static Analyzer.
* Its implementation in setrel() is somewhat scary. It's actually
okay, because that part of setrel() only runs within decl(). Other
callers don't reach it: update_main() because player->god != 0
there, and the rest because they never pass a rel < HOSTILE.
* Documentation is a bit vague.
SLOW_WAR hasn't been used in a public game in years. Fixing it is not
worth it, so remove it instead.
It assumed option SUPER_BARS enabled. It's disabled by default since
4.0.9.
It assumed people_damage = 0.4. It's 1.0 since 4.0.0.
It still claimed damaging a sector doesn't damage its planes. It does
since 4.0.9.
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.
Before Empire 2, nukes could be delivered only with bomb (special
mission 'n', airburst only) and launch (targeting sectors or
satellites only).
Empire 2 made nukes available for any kind of bombing, and for any
missile strike on sectors or ships. This included interdiction and
support missions. Nuclear-tipped anti-sats and bomb mission n were
removed.
Unfortunately, this was done in a messy way, which led to
inconsistencies and bugs. The problem is that ordinary damage affects
just the target, while nuke damage affects an area. Code dealing with
plane damage was designed for the former. Instead of rewriting it to
cope with area damage cleanly, nuke damage got shoehorned into
pln_damage(), the function to compute conventional plane damage, as a
side effect: computing damage blasted sectors in the area.
If the plane carried a nuke, pln_damage() returned zero (conventional)
damage. Without further logic, this simply bypassed the code to apply
damage to the target. This worked out okay when the target already
got damaged correctly by the side effect.
However, some targets are immune to the side effect: when interdicting
a move or explore command, the commodities being moved are not in any
sector.
For other targets, damage has effects other than damaging the target:
offensive and defensive support don't apply the (conventional) damage
to the target sector. Instead, they turn it into a combat bonus.
Without further logic, nuclear damage doesn't contribute to that.
To make all that work, pln_damage() returned the nuclear damage for
ground zero as well. Because a plane does either conventional or
nuclear damage, one of them is always zero.
Most callers simply ignored the nuclear damage, and applied only the
conventional damage.
Bug: land units and ships failed to retreat when pin-bombed or
missiled with a nuke. That's because they received zero conventional
damage.
The mission code flies planes and missiles and tallies their damage.
This mission damage included nuclear damage at ground zero (except for
missiles sometimes, see below), to make support and commodity
interdiction work. Unfortunately, this broke other things.
Bug: when bombers interdicted ships or land units, nukes first damaged
the ships or land units by the side effect, then again through mission
damage. Interdicting missiles had a special case to avoid this.
Bug: when interdicting move, explore or transport, nukes first damaged
the sector by the side effect, then again through mission damage's
collateral damage.
There may well be more bugs hiding in this mess.
The mess is not worth fixing. While the idea of interdicting and
supporting with nukes sounds kind of cool, I believe it's pretty
irrelevant in actual play.
Instead, go back to a variation of the original rules: nukes can be
delivered only through bomb mission 's' and launch at sectors.
Make arm reject marine missiles in addition to satellites, ABMs and
SAMs, and clear the mission. Make mission reject planes armed with
nukes. Oops when they show up in mission_pln_equip() anyway.
Make pln_equip() allow planes with nukes only for missions 's' and
't'.
Clean up pln_damage() to just compute damage, without side effect.
Change strat_bomb() and launch_missile() to detonate nukes. Simplify
the other callers. Parameter mission of msl_launch_mindam() is now
unused, remove it.
Missiles exploding on launch no longer set off their nukes. That was
pretty ridiculous anyway.
When a manually launched anti-sat hits, it now always destroys the
satellite. This matches what it does when it intercepts
automatically. Before, it only damaged the satellite.
Before, it took a sector argument, and targeted the lowest-numbered
satellite there. Rather inconvenient when your own satellite masks
one of the enemy's.
Moreover, the command could be abused to find all sectors with
satellites. Now it can "only" be abused to find satellite ids, and
whether they're in range. Still not ideal, but tolerable.
Replace the fixed $1 per ETU maintenance for capital/city sectors that
are at least 60% efficient by a configurable maintenance cost, payable
regardless of efficiency. The only change in the default
configuration is that inefficient capitals now pay maintenance.
Charging sector maintenance regardless of efficiency is consistent
with unit maintenance.
New struct dchrstr member d_maint and sector-chr selector maint. Make
show_sect_build() show it. Change produce_sect() to record
maintenance in new slot p_sect[SCT_MAINT] instead of abusing
p_sect[SCT_CAPIT]. Replace the "Capital maintenance" line in budget
by "Sector maintenance".