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.
Oops when a stale copy is written back, i.e. the processor was yielded
since the copy was made. Such bugs are difficult to spot. Sequence
numbers catch them when they do actual harm (they also catch different
bugs). Generation numbers catch them even when they don't.
New ef_generation to count generations. Call new ef_make_stale() to
increment it whenever the processor may be yielded.
New struct emptypedstr member generation. To conserve space, make it
a bit-field of twelve bits, i.e. generations are only recorded modulo
2^12. Make sure all members of unit empobj_storage share it. It is
only used in copies; its value on disk and in the cache is
meaningless. Copies with generation other than ef_generation are
stale. Stale copies that are a multiple of 2^12 generations old can't
be detected, but that is sufficiently improbable.
Set generation to ef_generation by calling new ef_mark_fresh() when
making copies in ef_read() and ef_blank(). nav_ship() and
fltp_to_list() make copies without going through ef_read(), and
therefore need to call ef_mark_fresh() as well. Also call it in
obj_changed() to make check_sect_ok() & friends freshen their argument
when it is unchanged.
New must_be_fresh() oopses when its argument is stale. Call it in
ef_write() to catch write back of stale copies.
Store them and ef_type in bit-fields.
Allocate eight bits for ef_type. Values range from 0 to EF_GAME
(currently 16), so this is plenty.
Allocate twelve bits for sequence numbers. Sequence number mismatches
are now missed when the numbers are equal modulo 2^12. Still
sufficiently improbable.
Common machines store the bit-fields in a 32 bit word. There are
twelve bits left in that word for future use. Total savings 16 bits,
which is exactly what the previous commit spent on wider uids on
common machines.
Before, they were stored as short. Wider uids use more space, but the
next commit will recover it by narrowing other members.
The use of short has always limited the number of ships, planes, land
units and nukes to SHRT_MAX (commonly 32768). Only the most extreme
games ever came close.
Commit 49780e2c (v4.3.12) added struct sctstr member sct_uid to make
struct empobj member uid work for sectors. This made the limit apply
to sectors as well. We've had games with more than 32768 sectors.
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".
Seamines and landmines share storage. Sea and bridge span sectors can
hold only sea mines, other sector types only landmines. Sector type
checks were missing or incorrect in several places:
* Seamines under bridge spans were mistaken for landmines in several
places:
- ground combat mine defense bonus, in get_mine_dsupport() and
stre(),
- land units retreating from bombs, in retreat_land1(),
- non-land unit ground movement (commands explore, move, transport,
and INTERDICT_ATT of military), in check_lmines(),
Fix them to check the sector type with new SCT_MINES_ARE_SEAMINES(),
SCT_LANDMINES().
* plane_sweep() mistook landmines for seamines in harbors. Bug could
not bite, because it's only called for sea sectors. Drop the bogus
check for harbor.
* Collapsing a bridge tower magically converted landmines into
seamines. Make knockdown() clear landmines.
Also use SCT_MINES_ARE_SEAMINES() and SCT_LANDMINES() in mine(),
landmine(), lnd_sweep() and lnd_check_mines(). No functional change
there.
Keep checking only for sea in pln_mine(), plane_sweep(),
retreat_ship1(), shp_sweep() and shp_check_one_mines(). This means
seamines continue not to work under bridges. Making them work there
is tempting, but as long as finding seamines clobbers the sector
designation in the bmap, it's better to have them in sea sectors only.
Historical notes:
Mines started out simple enough: you could mine sea and bridge spans,
and ships hit and swept mines in foreign sectors.
Chainsaw 2 introduced aerial mining and sweeping. Unlike ships,
planes could not mine bridge spans. plane_sweep() could sweep
harbors, which was wrong, but it was never called there, so the bug
could not bite.
Chainsaw 3 introduced landmines. The idea was to permit only seamines
in some sector types, and only landmines in the others, so they can
share storage. To figure out whether a sector has a particular kind
of mines, you need to check the sector type. Such checks already
existed in mine, drop and sweep, and they were kept unchanged. The
new lmine command also got the check. Everything else did not.
Ground movement and combat could hit and sweep seamines in bridge
spans. Ships could hit and sweep landmines in harbors.
Empire 2 fixed land unit movement (march, INTERDICT_ATT) not to
mistake seamines for landmines on bridge spans. It fixed ships not to
mistake landmines for seamines. The fix also neutered seamines under
bridge spans: ships could neither hit nor sweep them anymore. Both
fixes missed retreat.
Commit 5663713b (v4.3.1) made ship retreat consistent with other ship
movement.
Commit fbf9f15b removed SO, SE, but left their declarations behind.
Ditto commit 3aea20e1 for bigcity_dchr, and commit 08b94556 for
player_kill_idle.
Commit afa65c8f accidentally added a declaration for xedit().
With RAILWAYS, highway-like sectors double as rail. They need to be
at least 5% efficient to be operational, and then they additionally
extend rail into adjacent sectors that are at least 60% efficient.
New opt_RAILWAYS, SCT_HAS_RAIL(), sct_rail_track(). Update
sector_mcost(), bp_neighbors(), lnd_mar_one_sector() for RAILWAYS
mobility rules. Update sinfra(), spyline(), satdisp_sect() to show
rail track instead of rail infrastructure for RAILWAYS.
New virtual sector selector track, implemented by nsc_sct_track().
A sector type's terrain (struct dchrstr member d_terrain) is the
sector type of its underlying terrain. Sector types occuring in
d_terrain are terrain types, and must have their own type in
d_terrain. Players can change sector types only to those with the
same terrain.
The builtin configuration defines terrain types sea, mountain,
wasteland, wilderness and plains. It gives bridge span and tower
terrain sea, and everything else terrain wilderness. Hence, the stock
game remains unchanged.
Deities can use terrain to create sector types that can be developed
only in limited ways.
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().
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.
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.
Rename landgun() to fortgun() for consistency.
Make sure all members of unit empobj_storage share uid in addition to
ef_type.
Add matching uid member to struct gamestr, struct natstr and struct
sctstr, and set them.
Swap struct empobj members uid and own to make that easier, and update
struct comstr, struct lndstr, struct lonstr, struct loststr, struct
nwsstr, struct nukstr, struct plnstr, struct realmstr, struct shpstr,
struct trdstr, struct trtstr accordingly.
Note that the uid isn't properly set for struct nwsstr, struct lonstr,
struct trdstr, struct comstr and struct loststr. To be fixed.
get_empobj_chr() and emp_obj_chr_name() access struct sctstr member
sct_type through struct empobj member type. This is technically
non-portable, because the two differ in signedness. It was also
undocumented. Fix by making sct_type signed. sct_newtype as well,
for consistency.
map_char() uses unsigned char for a sector type argument. Change that
to int. Matches how this is done elsewhere.
(lndstr, plnstr, sctstr, shpstr): Change timestamp members lnd_access,
pln_access, sct_access, shp_access from real time (time_t) to ETUs
within a turn (short).
(land_ca, plane_ca, sect_ca, ship_ca): Update accordingly.
(build_ship, build_land, build_bridge, build_plane, build_tower)
(explore, check_trade, bsanct, takeover, takeover_ship)
(takeover_land): Use game_tick_to_now() instead of time() to update
the timestamp. Change check_trade(), takeover_ship(), takeover_land()
to do that only when MOB_ACCESS is enabled, for consistency.
(lupgr, supgr, pupgr, takeover_ship): Don't touch the timestamp where
mobility isn't touched either.
(sct_do_upd_mob, shp_do_upd_mob, lnd_do_upd_mob, pln_do_upd_mob): Use
game_tick_to_now() instead of increase_mob() to compute ETUs since
the timestamp and update the timestamp. Closes#1012699.
(increase_mob): Remove.
(mob_sect, mob_ship, mob_land, mob_plane): sct_do_upd_mob() & friends
no longer do the right thing at the update. Use game_reset_tick() and
pass its result directly to do_mob_sect() & friends. This is only
correct when argument is etu_per_update, which it always is. Remove
parameter. Callers changed.
(do_mob_sect, do_mob_ship, do_mob_land, do_mob_plane): Oops on
negative argument.
(mob_acc_globals, timestampfil, mobupdate, updating_mob)
(update_all_mob, timestamp_fixing, update_timestamps, mobility_check):
The mobupdate command was important to let deities manually
synchronize mobility updating with updates. That's no longer needed.
The code behind it is somewhat hairy and ugly, and updating it to work
with the Empire clock is just not worth it. Remove. Users changed.
(player_coms): Update accordingly.
(upda): Remove display of mobility updating state.
(mobility_init): No need to fix up mobility on startup, as the Empire
clock runs normally even when the server is down. Remove. Caller
changed.
other. Ensure headers in include/ can be included in any order
(except for econfig-spec.h, which is special). New header types.h to
help avoid inclusion cycles. Sort include directives. Remove some
superflous includes.
oprange, show_mission, nameofitem, build_mission_list_type,
unit_map, xdvisible, trdswitchown, ontradingblock, trad, check_trade,
unit_type_name, start_stop_unit, scut, scra, mission, multifire,
perform_mission, fuel, NSC_GENITEM): Replace struct genitem with
struct empobj. Remove genitem.h and create a new file empobj.h.
Replace multiple instances of unions of ef_type structures with
one standard union empobj_storage which is a superset of the individual
instances.
plus one. Users changed. This indirectly fixes off-by-one loop
bounds in budg(), show_sect_build(), show_sect_stats() and
show_sect_capab(). The show bugs were harmless: the loops ran into
the sentinel, which they ignore. The budg bug was serious: the loop
ran into the entries for SCT_EFFIC. This lead to a bogus line in the
budget, printing of a null pointer, and doubled sector build cost.
Budget priorities masked this bug until rev. 1.25.
by float d_mob0 and d_mob1 (straight costs). Impassable terrain now
encoded as negative d_mob0 instead of zero d_mcst. Users changed.
sect.config updated.
(dchr_ca): Replace selectors mcst and emcst by mob0 and mob1.
(show_sect_stats): Show real mobility costs.
instead of opt_DEFENSE_INFRA.
(improve): Test for it.
(show_sect_build): Show only enabled infrastructure.
(opt_DEFENSE_INFRA): Remove. Deities can edit infra.config instead.
(improve): Dumb down prompt.
is a linear function of sector efficiency, with cost at 0% given by
dchstr member d_mcst and cost at 100% given by d_emcst. The latter
used to be d_mcst - 1. Mountain cost is no longer a special case.
Road infrastructure now reduces cost up to 90%, linear in road
efficiency (used to be close to that, but non-linear). Same for rail
infrastructure, but 99%. Double land unit minimum cost to 0.02.
Change land unit cost penalty in newly taken land to an extra 0.2
instead of a minimum of 0.2.
(dchrstr): New member d_emcst. sector.config updated, with some
changes: cost of mountain now ranges from 2.4 to 1.2 instead of 2.174
to 1.304, wildernes 0.4 instead of 0.6 to 0.4, highway, bridge head,
bridge span and tower from 0.4 to 0.001 instead of 0.2 to 0.001.
While I'm at it, make bridge head match highway stats (dstr and value
reduced).
(show_sect_stats): Show d_emcst.
(dchr_ca): New selector emcst for d_emcst.
(att_mobcost): New.
(ask_olist, take_move_in_mob): Use it. Attacking land units can now
use roads and suffer the newly taken penalty. No difference in most
cases, because the penalty commonly cancels the road bonus.
(get_mob_support, calc_mobcost, ask_move_in_off): Use it. No
functional change now; ensures that military's attack mobility cost
will stay consistent with move cost.
(MOB_NONE): Unused, remove.
(sector_mcost): Simplify.
move costs, but failed to make A* use these costs. This broke land
unit path finding. Fix:
(MOB_ROAD, MOB_MOVE, MOB_MARCH): Split MOB_ROAD into MOB_MOVE and
MOB_MARCH. Users changed.
(lnd_mobcost, sector_mcost): Move minimum mobcost logic to
sector_mcost(), where it is visible to A*. Also fixes unit reaction
path cost.
(lnd_path): Fix confusing message: don't claim there's no path when
all we really know is that there's no railway.