This doesn't overwrite the sector file completely anymore, it just
sets sct_type, sct_newtype, sct_elev and sct_coastal. You really need
to run files first now.
Commit f33b96b1 (v4.3.12) made files again set timestamps. That was
intentionally suppressed in commit 990eb46b (v4.3.10), because it
facilitates attacks against the PRNG. Commit 8f98e53a (v4.3.0) had
added it as a feature.
Fix by making files's main() pass new flag EFF_NOTIME to ef_open().
Implement the flag in do_write().
do_write() sets the timestamp from a parameter. All callers pass
time(), and don't use that value themselves. Call time() in do_write
and remove the parameter.
Commit f33b96b1 made ef_flush(), ef_write() and ef_extend() update
timestamps automatically. Change ef_write() and ef_extend() to do
that even when table is privately mapped, by making do_write() cope
with privately mapped tables. Current users don't care, but it's a
saner interface.
Make server check game state file sizes on startup
Certain tables have a fixed size depending on configuration: EF_SECTOR
has WORLD_SZ() elements, EF_NATION, EF_MAP and EF_BMAP have MAXNOC
elements, and EF_REALM has MAXNOC * MAXNOR elements. Bad things
happen if the files backing them are shorter.
Pass expected size to ef_open(), and make it fail when the actual size
differs.
Fix starvation not to starve one more than it should
Commit 109dad1b (v4.3.5) promised to round victim fractions down, but
got it wrong for odd population when exactly half of it rounded down
could be fed. This could starve the last man on a boat or land unit.
Fix famine_victims().
The value of diffx() had the wrong sign when the arguments differed by
WORLD_X / 2. Same for diffy() and WORLD_Y / 2. satmap() used them to
find the vector from map center to ship or land unit to put on the
map, and got incorrect values for ships and land units directly
opposite to the center in x or y. The bug made satmap() read a
pointer out bounds of its malloced radbuf[], and then write through
that with unpredictable consequences.
Broken in 4.2.12. The original bug was in Empire 1.1: it
miscalculated where to put ships on the map (no crash). An incomplete
fix for radmap() and satmap() appeared in Chainsaw 2 (still no crash).
radmap() got fixed correctly in Chainsaw 3, but satmap() was
forgotten. That one got "fixed" in 4.2.7, and again in 4.2.12, but
both "fixes" were flawed and could crash.
Fix by backing out the flawed fixes and adopting the fix from radmap()
instead.
Commit da8a1dae (v4.3.12) introduced virtual selectors, but neglected
to update xundump. Xundump can't work for them, because they don't
provide a setter method.
This didn't actually break anything, because all virtual selectors
have flag NSC_EXTRA set, or are in table EF_VERSION, which xundump
refuses to touch.
Make deffld() oops on virtual selector, just to be safe.
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().
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().
Fix transfer of loans and market lots on sack of capital
Fix caploss() to transfer only signed loans. Before, it transferred
any loan with a non-zero duration, which included loan offers, and
could claim to tranfer nonexistent loans.
Fix caploss() not to claim transfer of nonexistant market lots when
country 0 sacks a capital.
Remove useless sanctuary break logic from designate
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.
Change fire to always fire guns when the target is beyond range
multifire() drops depth charges if the target is a submarine, else it
fires guns. It fails if the target is out of range. But players
could still find out whether the target is a sub then, because depth
charge shell use differs from gun fire shell use. This loophole
existed before 4.0.6, and was reopened by commit a3ad623b (v4.3.12).
Change multifire() to always use guns if the target is out of range.
While there, treat failure from shp_dchrg() and shp_fire() the same,
so that the player can't distinguish the two cases. Failure there
should not happen.
Commit a3ad623b (v4.3.12) made depth charging fail when there's just
one shell. This let players find all submarine uids. It basically
reopened the loophole closed in commit aa26c53e (v4.2.20).
Fix by making shp_dchrg() with just one shell succeed and return
damage like fire from one gun.
Fix fire command to detect when the firing object changes
multifire() failed to take into account that the firing firing sector,
ship or land unit can change while it is getting the target argument.
It thus clobbered any updates made to the firing object while it was
sleeping for the target argument. Abusable. Broken when Chainsaw
introduced MULTIFIRE.
Journal input of special cookies "ctld" and "aborted"
The latter is necessary to interpret the journal correctly. The
former isn't, as it should always lead to a logout straight away, but
treating it just the same is simple and doesn't hurt.
Behavior differs for the following scenario: if, while the thread
sleeps in io_input() called from recvclient(), at least one line of
input arrives and the thread gets awakened by the update aborting
commands, then the old code throws away the first line of input, but
the new code doesn't.
Commit 7ca4f412 fixed tracking of planes flying a sortie by marking
them with flag PLN_LAUNCHED. It failed to write SAMs and planes
flying missions back to the plane file, in sam_intercept() and
mission_pln_arm(). The only known problem with that is fairly
harmless: when the mission damages planes on the ground, the planes
flying it get damaged as if they were still sitting in their bases,
but the damage gets wiped out when they land.
The same issue applies to missiles. So they need to be tracked as
well. Do that in msl_hit().
While there, remove a few redundant PLN_LAUNCHED sanity checks.
When fixing planes stuck in the air, we fixed them only in memory, so
when a fixed plane wasn't written to disk for other reasons before the
next game start, it had to be fixed again.
Change pln_zap_transient_flags() to write them out.
These *are* called while player->aborted. Could be avoided, but: the
reason for not wanting to prompt then is to have each prompt consume a
line of input. That's actually not feasible, because when we wait for
an argument (after prompting for it) when the update aborts commands,
we can't consume the argument we prompted for.
Checking l_ammo before lnd_dam() oopses when something attempts to
fire from a land unit type that can't fire (l_dam == 0) and uses no
ammo. Such usage is perfectly fine. Move the check to the correct
place.
Change oops() to call the new oops_handler function pointer instead of
offering a fixed set of actions. Change server's main() to install a
handler for the action requested by -E.
Some losing implementations of strptime() such as FreeBSD's happily
succeed when they fully consumed the first argument, regardless of
whether they matched the full second argument or not. This causes
lines without directives to be interpreted as "next Sunday".
babies() rounded the maximum number of babies permitted by food. When
this rounded up, grow_people() could use more food than available, and
the sector's food could become negative. Fix by always rounding down.
Ron Koenderink [Fri, 28 Mar 2008 02:07:11 +0000 (20:07 -0600)]
Add missing thread yield system call.
This change fixes a bug where the threads were not treated
fairly. Before the fix, empth_yield would only yield to
threads already waiting hThreadMutex mutex. It would not
yield to other threads ready to run from the release of other
mutexes. An example of this is that the update task did
not start when force command was issued from script sequence.
Pass struct natstr * instead of natid to virtual selectors
This is because we want to define them in src/lib/global/, and code
there can't use getnatp(), because that requires
src/lib/common/file.c. Which renders a cnum parameter pretty useless.
Virtual selectors requiring code from common/ could well come up again
in the future, but let's not worry about that now.
Replace laun()'s base checking code by pln_airbase_ok()
This outlaws launch from unowned sectors. Also, non-VTOL missiles
require an efficient airfield now, except that such missiles don't
exist currently, because init_plchr() makes all missiles VTOL.
Fix launch to require petrol for launching satellites
launch_sat() failed to call msl_equip(). Change msl_equip() to take
the mission character as argument, because the old hardcoded 'p' isn't
appropriate for satellites. Best fit for satellites is 'r' for
reconnaissance, but mission_pln_equip() doesn't accept that
(pln_equip() does). Fix that as well.
Use XYOFFSET() instead of sctoff() in sector iterators
Old code didn't check value of sctoff() for success. But it can't
fail, because we already took care of the condition that can make it
fail. Moreover, the arguments are already normalized. Therefore, we
can just call XYOFFSET().
The code to find a suitable sanctuary location is flawed: to find
space and resources around the location, it does a depth-first search
limited to 300 sectors. Pretty useless when the limit is reached. A
breadth-first search would work, but why bother? This feature is
obscure and rarely (if ever) used: no conscientious deity would use it
for a real game, and for blitzes fairland does a better job. Remove
it.